Authored by 陈峰

Merge branch 'master' of http://git.yoho.cn/fe/yoho-community-web

@@ -4,6 +4,7 @@ import Layouts from './layouts'; @@ -4,6 +4,7 @@ import Layouts from './layouts';
4 import Products from './products'; 4 import Products from './products';
5 import Comments from './comments'; 5 import Comments from './comments';
6 import YohoActionSheet from './action-sheet'; 6 import YohoActionSheet from './action-sheet';
  7 +import TextEllipsis from './textellipsis'
7 8
8 export default [ 9 export default [
9 ...Widgets, 10 ...Widgets,
@@ -11,5 +12,6 @@ export default [ @@ -11,5 +12,6 @@ export default [
11 ...Layouts, 12 ...Layouts,
12 ...Products, 13 ...Products,
13 ...Comments, 14 ...Comments,
14 - ...YohoActionSheet 15 + ...YohoActionSheet,
  16 + ...TextEllipsis
15 ]; 17 ];
  1 +import TextEllipsis from './textellipsis';
  2 +
  3 +export default [
  4 + TextEllipsis
  5 +];
  1 +<template>
  2 + <div class="h-text-ellipsis" :style="{width: width ? width + 'px': 'unset'}">
  3 + <slot name="before" class="h-text-ellipsis-before"></slot>
  4 + <span class="text-ellipsis-limit-text" :key="keyIndex" :content="text">{{text}}</span>
  5 + <span class="h-text-ellipsis-more" v-show='oversize'><slot name="more"></slot></span>
  6 + <slot name="after" class="h-text-ellipsis-after"></slot>
  7 + </div>
  8 +</template>
  9 +<script>
  10 +
  11 +export default {
  12 + name: 'TextEllipsis',
  13 + props: {
  14 + text: String,
  15 + height: Number,
  16 + width: {
  17 + Number,
  18 + default: 0
  19 + },
  20 + isLimitHeight: {
  21 + type: Boolean,
  22 + default: true
  23 + }
  24 + },
  25 + data() {
  26 + return {
  27 + keyIndex: 0,
  28 + oversize: false,
  29 + isHide: false
  30 + };
  31 + },
  32 + watch: {
  33 + isLimitHeight() {
  34 + this.init();
  35 + },
  36 + text() {
  37 + this.init();
  38 + },
  39 + height() {
  40 + this.init();
  41 + },
  42 + width() {
  43 + this.init();
  44 + }
  45 + },
  46 + mounted() {
  47 + this.init();
  48 + },
  49 + methods: {
  50 + init() {
  51 + this.oversize = false;
  52 + this.keyIndex += 1;
  53 + let more = this.$el.querySelector('.h-text-ellipsis-more');
  54 +
  55 + more.style.display = 'none';
  56 + if (this.isLimitHeight) {
  57 + this.limitShow();
  58 + }
  59 + },
  60 + limitShow() {
  61 + this.$nextTick(() => {
  62 + let textDom = this.$el.querySelector('.text-ellipsis-limit-text');
  63 + let title = this.$el;
  64 + let more = this.$el.querySelector('.h-text-ellipsis-more');
  65 + let n = 1000;
  66 +
  67 + if (textDom) {
  68 + if (title.offsetHeight > this.height) {
  69 + more.style.display = 'inline-block';
  70 + let text = this.text;
  71 +
  72 + while (title.offsetHeight > this.height && n > 0) {
  73 +
  74 + if (title.offsetHeight > this.height * 3) {
  75 + textDom.innerText = text = text.substring(0, Math.floor(text.length / 2));
  76 + } else {
  77 + textDom.innerText = text = text.substring(0, text.length - 1);
  78 + }
  79 + n--;
  80 + }
  81 + this.$emit('hide');
  82 + this.isHide = true;
  83 + } else {
  84 + this.$emit('show');
  85 + this.isHide = false;
  86 + }
  87 + }
  88 + });
  89 + }
  90 + }
  91 +};
  92 +</script>
  93 +
  94 +<style lang="scss" scoped>
  95 + .text-ellipsis-limit-text {
  96 + white-space: pre-wrap;
  97 + }
  98 +</style>
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 <div v-if="avatars" class="avatar-list-wrap"> 2 <div v-if="avatars" class="avatar-list-wrap">
3 <ul v-if="avatarList" class="avatar-list"> 3 <ul v-if="avatarList" class="avatar-list">
4 <li v-for="(item, index) in avatarList" :key="index" :style="item.style"> 4 <li v-for="(item, index) in avatarList" :key="index" :style="item.style">
5 - <WidgetAvatar :src="item.src" width="100" height="100"></WidgetAvatar> 5 + <WidgetAvatar :src="item.src" :width="100" :height="100"></WidgetAvatar>
6 </li> 6 </li>
7 <li v-if="hasMore"> 7 <li v-if="hasMore">
8 <img src="//img12.static.yhbimg.com/evidenceImages/2019/01/30/17/02fdbbddfc30f18868f91406eed8a70fb9.png?imageMogr2/thumbnail/130x130/extent/130x130/background/d2hpdGU=/position/center/quality/90"> 8 <img src="//img12.static.yhbimg.com/evidenceImages/2019/01/30/17/02fdbbddfc30f18868f91406eed8a70fb9.png?imageMogr2/thumbnail/130x130/extent/130x130/background/d2hpdGU=/position/center/quality/90">
@@ -119,7 +119,7 @@ @@ -119,7 +119,7 @@
119 }; 119 };
120 </script> 120 </script>
121 121
122 -<style type="css"> 122 +<style type="scss">
123 .icon-btn { 123 .icon-btn {
124 display: inline-block; 124 display: inline-block;
125 line-height: 1; 125 line-height: 1;
1 <template> 1 <template>
2 - <div></div> 2 + <div v-if="topic" class="topic-wrap">
  3 + #{{topic}}
  4 + </div>
3 </template> 5 </template>
4 6
5 <script> 7 <script>
6 export default { 8 export default {
7 - name: 'WidgetTopic' 9 + name: 'WidgetTopic',
  10 + props: {
  11 + topic: String
  12 + }
8 }; 13 };
9 </script> 14 </script>
  15 +
  16 +<style type="scss">
  17 + .topic-wrap {
  18 + display: inline-block;
  19 + line-height: 1;
  20 + vertical-align: middle;
  21 + font-size: 20px;
  22 + line-height: 44px;
  23 + padding: 0 12px;
  24 + border: 2px solid #222;
  25 + border-radius: 2px;
  26 + box-sizing: border-box;
  27 + }
  28 +</style>
1 <template> 1 <template>
2 <div class="header"> 2 <div class="header">
3 <div class="avatar-wrapper"> 3 <div class="avatar-wrapper">
4 - <img class="avatar" src=""> 4 + <img class="avatar" :src="avatar">
5 <span class="name">{{name}}</span> 5 <span class="name">{{name}}</span>
6 </div> 6 </div>
7 7
8 <div class="close" @click="close"> 8 <div class="close" @click="close">
  9 + <i class="iconfont icon-close icon"></i>
9 </div> 10 </div>
10 </div> 11 </div>
11 </template> 12 </template>
@@ -16,7 +17,7 @@ export default { @@ -16,7 +17,7 @@ export default {
16 props: { 17 props: {
17 avatar: { 18 avatar: {
18 type: String, 19 type: String,
19 - default: '' 20 + default: '//tvax2.sinaimg.cn/crop.0.0.828.828.50/006IPkwKly8fyhr791kkxj30n00n0q3u.jpg'
20 }, 21 },
21 name: { 22 name: {
22 type: String, 23 type: String,
@@ -28,7 +29,8 @@ export default { @@ -28,7 +29,8 @@ export default {
28 }, 29 },
29 methods: { 30 methods: {
30 close() { 31 close() {
31 - this.emit('close'); 32 + console.log('close');
  33 + this.$emit('close');
32 } 34 }
33 } 35 }
34 }; 36 };
@@ -41,8 +43,7 @@ export default { @@ -41,8 +43,7 @@ export default {
41 justify-content: space-between; 43 justify-content: space-between;
42 padding: 18px 32px 54px; 44 padding: 18px 32px 54px;
43 height: 128px; 45 height: 128px;
44 - background-color: black;  
45 - opacity: 0.8; 46 + background-color: rgba(0, 0, 0, 0.8);
46 } 47 }
47 48
48 .avatar-wrapper { 49 .avatar-wrapper {
@@ -64,4 +65,12 @@ export default { @@ -64,4 +65,12 @@ export default {
64 margin-left: 12px; 65 margin-left: 12px;
65 } 66 }
66 67
  68 +.close {
  69 + color: white;
  70 +}
  71 +
  72 +.icon {
  73 + font-size: 55px;
  74 +}
  75 +
67 </style> 76 </style>
  1 +<template>
  2 + <div class="footer">
  3 + <TextEllipsis :text="text" class="desc" :isLimitHeight="isLimitHeight" :height="68">
  4 + <template slot="more"><span>...</span><span class="link" @click="onClick">展开</span></template>
  5 + <span slot="after" v-if="!isLimitHeight" @click="isLimitHeight=true"></span>
  6 + </TextEllipsis>
  7 +
  8 + <div class="product-wrapper">
  9 + <div class="products">
  10 + <Products></Products>
  11 + </div>
  12 + <div class="share"></div>
  13 + </div>
  14 + </div>
  15 +</template>
  16 +
  17 +<script>
  18 +
  19 +import Products from './products'
  20 +
  21 +export default {
  22 + name: 'DescFooter',
  23 + components: {
  24 + Products
  25 + },
  26 + data() {
  27 + return {
  28 + text: '很好,能抢到真的不容易!整体感觉很舒服,庆幸下手一定要快准狠!如果能够再抢到一双就更好了,下次加买很多双,很好,能抢到真的不容易!整体感觉很舒服,庆幸下手一定要快准狠!如果能够再抢到一双就更好了,下次加买很多双',
  29 + isLimitHeight: true
  30 + };
  31 + },
  32 + methods: {
  33 + onClick() {
  34 + this.isLimitHeight = false;
  35 + }
  36 + },
  37 +};
  38 +</script>
  39 +
  40 +<style lang="scss" scoped>
  41 +
  42 +.footer {
  43 + position: relative;
  44 + min-height: 280px;
  45 + background: rgba(0, 0, 0, 0.5);
  46 +}
  47 +
  48 +.desc {
  49 + min-height: 134px;
  50 + font-size: 26px;
  51 + color: white;
  52 + letter-spacing: 0.01px;
  53 + padding: 30px 28px 0 28px;
  54 +}
  55 +
  56 +.product-wrapper {
  57 + height: 166px;
  58 + padding: 0 28px;
  59 +}
  60 +
  61 +.products {
  62 + display: inline-block;
  63 + width: 290px;
  64 + height: 100px;
  65 + background-color: white;
  66 + margin-top: 36px;
  67 +}
  68 +
  69 +.link {
  70 + color: #4a90e2;
  71 +}
  72 +</style>
  1 +<template>
  2 + <div class="order-wrapper">
  3 + <!-- <Test class="test"></Test> -->
  4 + <Slide :data="list"
  5 + :loop="false"
  6 + :autoPlay="false"
  7 + class="slide-container"
  8 + @change="slideChangeHandler"
  9 + :threshold="0.05"
  10 + @options="slideOptions"
  11 + >
  12 + <SlideItem v-for="i in list">
  13 + <div class="image-wrapper">
  14 + <img class="image" :src="i" alt="">
  15 + </div>
  16 + </SlideItem>
  17 +
  18 + <template slot="dots"><i></i></template>
  19 + </Slide>
  20 +
  21 + <div class="image-preview-footer">
  22 + <span class="image-preview-counter">{{currentPageIndex + 1}}/{{list.length}}</span>
  23 + </div>
  24 +
  25 + <AvatarHeader class="avatar-wrapper"></AvatarHeader>
  26 +
  27 + <DescFooter class="footer-wrapper"></DescFooter>
  28 + </div>
  29 +</template>
  30 +
  31 +<script>
  32 +
  33 +import {Slide} from 'cube-ui';
  34 +import AvatarHeader from './avatar-header';
  35 +import DescFooter from './desc-footer';
  36 +import Test from './test'
  37 +
  38 +const img = require('statics/image/showorder/test.png')
  39 +
  40 +export default {
  41 + name: 'ShowOrderItem',
  42 + components: {
  43 + AvatarHeader,
  44 + DescFooter,
  45 + Slide,
  46 + SlideItem: Slide.Item,
  47 + Test
  48 + },
  49 + data() {
  50 + return {
  51 + list: [
  52 + 'https://wx1.sinaimg.cn/mw1024/686d7361ly1fpha0mpd5uj21hc0tyws2.jpg',
  53 + 'https://wx1.sinaimg.cn/mw1024/686d7361ly1fpha0ncnnej21hc0zetxo.jpg',
  54 + 'https://wx1.sinaimg.cn/mw1024/686d7361ly1fpha0mqvu5j21hc0zkgzz.jpg',
  55 + img.toString()
  56 + ],
  57 +
  58 + currentPageIndex: 0,
  59 + slideOptions: {
  60 + listenScroll: true,
  61 + probeType: 3,
  62 + click: false,
  63 + directionLockThreshold: 0,
  64 + stopPropagation: true
  65 + },
  66 + testimg: img
  67 + };
  68 + },
  69 + methods: {
  70 + close() {
  71 +
  72 + },
  73 + onclick(e) {
  74 + console.log('huangtao12=>',e);
  75 + },
  76 + slideChangeHandler(currentPageIndex) {
  77 + this.currentPageIndex = currentPageIndex;
  78 + }
  79 + }
  80 +};
  81 +</script>
  82 +
  83 +<style lang="scss" scoped>
  84 +.order-wrapper {
  85 + width: 100%;
  86 + height: 100%;
  87 + position: relative;
  88 + background-image: url('~statics/image/showorder/sd_bg@2x.png');
  89 + background-size: cover;
  90 +}
  91 +
  92 +.avatar-wrapper {
  93 + position: absolute;
  94 + width: 100%;
  95 + top: 0;
  96 + z-index: 2;
  97 +}
  98 +
  99 +.image-wrapper {
  100 + display: flex;
  101 + align-items: center;
  102 + justify-content: center;
  103 + height: 100%;
  104 +
  105 + .image {
  106 + width: 100%;
  107 + }
  108 +}
  109 +
  110 +.image-preview-footer {
  111 + position: absolute;
  112 + width: 180px;
  113 + height: 60px;
  114 + background: rgba(0, 0, 0, 0.4);
  115 + top: 110px;
  116 + right: -60px;
  117 + border-radius: 30px;
  118 +}
  119 +
  120 +.image-preview-counter {
  121 + margin-left: 40px;
  122 + font-size: 26px;
  123 + color: white;
  124 + height: 60px;
  125 + line-height: 60px;
  126 +}
  127 +
  128 +.footer-wrapper {
  129 + position: absolute;
  130 + left: 0;
  131 + right: 0;
  132 + bottom: 0;
  133 +}
  134 +
  135 +.test {
  136 + position: absolute;
  137 + top: 50px;
  138 + left: 100px;
  139 +}
  140 +</style>
  1 +<template>
  2 + <div class="product-wrapper">
  3 + <img :src="url" alt="" srcset="">
  4 + <div class="price">{{price}}</div>
  5 + </div>
  6 +</template>
  7 +
  8 +<script>
  9 +export default {
  10 + name: 'ProductItem',
  11 + props: {
  12 + pid:{
  13 + type: String,
  14 + default() {
  15 + return '1212'
  16 + }
  17 + },
  18 + url: {
  19 + type: String,
  20 + default() {
  21 + return '//tvax2.sinaimg.cn/crop.0.0.828.828.50/006IPkwKly8fyhr791kkxj30n00n0q3u.jpg';
  22 + }
  23 + },
  24 + price: {
  25 + type: String,
  26 + default() {
  27 + return '¥121314';
  28 + }
  29 + }
  30 + }
  31 +}
  32 +</script>
  33 +
  34 +<style lang="scss" scoped>
  35 +.product-wrapper {
  36 + display: inline-block;
  37 + position: relative;
  38 + width: 100px;
  39 + height: 100px;
  40 +}
  41 +
  42 +.price {
  43 + width: 100%;
  44 + height: 28px;
  45 + line-height: 28px;
  46 + font-size: 20px;
  47 + position: absolute;
  48 + bottom: 0;
  49 + text-align: center;
  50 + background: rgba(0,0,0,0.50);
  51 + color: white;
  52 +}
  53 +
  54 +
  55 +</style>
  1 +<template>
  2 + <div class="products-wrapper">
  3 + <ProductItem class="item" v-for="i in 3"></ProductItem>
  4 + </div>
  5 +</template>
  6 +
  7 +<script>
  8 +
  9 +import ProductItem from './product-item'
  10 +
  11 +export default {
  12 + name: 'Products',
  13 + props: {
  14 + list: {
  15 + type: Array,
  16 + default() {
  17 + return [];
  18 + }
  19 + }
  20 + },
  21 + components: {
  22 + ProductItem
  23 + }
  24 +}
  25 +</script>
  26 +
  27 +<style lang="scss" scoped>
  28 +.products-wrapper {
  29 + overflow: scroll;
  30 +}
  31 +
  32 +.item {
  33 + margin-right: 20px;
  34 +}
  35 +</style>
1 <template> 1 <template>
2 <Layout> 2 <Layout>
3 - <Header slot="header"></Header> 3 + <Slide ref="slide"
  4 + :data="list"
  5 + :loop="false"
  6 + :autoPlay="false"
  7 + direction="vertical"
  8 + class="slide-container"
  9 + :showDots="false"
  10 + @scroll-end="onChange"
  11 + :speed="1000"
  12 + :threshold="0.05"
  13 + :options="scrollOpts"
  14 + >
  15 + <SlideItem v-for="i in list">
  16 + <OrderSlideItem></OrderSlideItem>
  17 + </SlideItem>
  18 + </Slide>
4 </Layout> 19 </Layout>
5 </template> 20 </template>
6 21
7 <script> 22 <script>
8 23
9 -import {Scroll, Loading} from 'cube-ui';  
10 -import Header from './components/header'; 24 +import {Slide} from 'cube-ui';
  25 +import OrderSlideItem from './components/order-slide-item';
11 26
12 export default { 27 export default {
13 name: 'ShowOrderPage', 28 name: 'ShowOrderPage',
14 components: { 29 components: {
15 - Loading,  
16 - Scroll,  
17 - Header 30 + Slide,
  31 + SlideItem: Slide.Item,
  32 + OrderSlideItem,
18 }, 33 },
19 data() { 34 data() {
20 return { 35 return {
21 - list: [], 36 + list: [
  37 + {
  38 + url: 'http://www.didichuxing.com/',
  39 + image: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3978382133,2176310874&fm=27&gp=0.jpg'
  40 + },
  41 + {
  42 + url: 'http://www.didichuxing.com/',
  43 + image: '//webapp.didistatic.com/static/webapp/shield/cube-ui-examples-slide02.png'
  44 + },
  45 + {
  46 + url: 'http://www.didichuxing.com/',
  47 + image: '//webapp.didistatic.com/static/webapp/shield/cube-ui-examples-slide02.png'
  48 + },
  49 + ],
  50 + scrollOpts: {
  51 + deceleration: 0.0001,
  52 + listenScroll: true,
  53 + probeType: 3,
  54 + click: true,
  55 + directionLockThreshold: 0,
  56 + }
22 }; 57 };
23 }, 58 },
  59 + mounted() {
  60 + },
24 methods: { 61 methods: {
25 - close() {  
26 - 62 + onChange(i) {
  63 + this.$nextTick(() => {
  64 + this.list.shift();
  65 + this.list.push({
  66 + url: 'http://www.didichuxing.com/',
  67 + image: '//webapp.didistatic.com/static/webapp/shield/cube-ui-examples-slide03.png'
  68 + });
  69 + });
  70 + },
  71 + clickHandler(e) {
  72 + console.log(e);
27 } 73 }
28 } 74 }
29 }; 75 };
30 </script> 76 </script>
31 77
32 -<style> 78 +<style lang="scss" scoped>
  79 +
  80 +.slide-container {
  81 + /deep/ .cube-slide-item {
  82 + width: 100%;
  83 + }
  84 +}
  85 +
33 </style> 86 </style>