Commit d495801abedc7d8eab28f34c0704c1bd97013574

Authored by 尹聃
Exists in master

Merge branch 'master' of 121.40.31.31:jp/gulu-vue

src/components/CommodityCard/CommodityCard.vue
... ... @@ -3,10 +3,14 @@
3 3 class="card"
4 4 @tap="toGoods(goods.id?goods.id:goods.pid,goods.sk_id)"
5 5 >
6   - <image
  6 + <easy-loadimage mode="widthFix"
  7 + :scroll-top="scrollTop"
  8 + :image-src="goods.imgurl?goods.imgurl:goods.pic"
  9 + :viewHeight="viewHeight"></easy-loadimage>
  10 +<!-- <image
7 11 mode="widthFix"
8 12 :src="goods.imgurl?goods.imgurl:goods.pic"
9   - ></image>
  13 + ></image> -->
10 14 <view class="name">{{goods.name?goods.name:goods.p_name}}</view>
11 15 <view class="info">
12 16 <view class="priceBox">
... ... @@ -22,7 +26,10 @@
22 26 </template>
23 27  
24 28 <script>
  29 +import easyLoadimage from '@/components/EasyLoadimage/EasyLoadimage.vue'
  30 +// const MockData = require('@/static/easy-loadimage/mock-data.json')
25 31 export default {
  32 + components:{easyLoadimage},
26 33 props: {
27 34 /**
28 35 * 商品数据
... ... @@ -37,15 +44,17 @@ export default {
37 44 trade_num: String,
38 45 goodType: String,
39 46 },
40   -
  47 + scrollTop:Number,
  48 + viewHeight:Number,
41 49 },
42 50 created () {
43 51 },
44 52 data () {
45 53 return {
46   -
  54 +
47 55 }
48 56 },
  57 +
49 58 methods: {
50 59 toGoods (id, skId) {
51 60 console.log('---', '../frameDetail/frameDetail?pid=' + id + '&sk_id=' + skId)
... ... @@ -61,6 +70,7 @@ export default {
61 70 </script>
62 71  
63 72 <style lang="scss">
  73 +
64 74 image {
65 75 width: 100%;
66 76 height: 120rpx;
... ...
src/components/EasyLoadimage/EasyLoadimage.vue
... ... @@ -0,0 +1,170 @@
  1 +<template>
  2 + <view class="easy-loadimage" :id="uid">
  3 + <image class="origin-img" :src="imageSrc?imageSrc:defaultImg" :mode="mode"
  4 + v-if="loadImg&&!isLoadError"
  5 + v-show="showImg"
  6 + :class="{'no-transition':!openTransition,'show-transition':showTransition&&openTransition}"
  7 + @load="handleImgLoad"
  8 + @error="handleImgError">
  9 + </image>
  10 + <view class="loadfail-img" v-else-if="isLoadError"></view>
  11 + <view :class="['loading-img',loadingMode]" v-show="!showImg&&!isLoadError"></view>
  12 +
  13 + </view>
  14 +</template>
  15 +<script>
  16 +// 生成全局唯一id
  17 +function generateUUID() {
  18 +    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  19 +        let r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
  20 +        return v.toString(16);
  21 +    })
  22 +}
  23 +export default{
  24 + props:{
  25 + imageSrc:{
  26 + type: String,
  27 + },
  28 + mode:{
  29 + type: String,
  30 + },
  31 + scrollTop:{
  32 + type: Number,
  33 + },
  34 + loadingMode:{
  35 + type: String,
  36 + default:'looming-gray'
  37 + },
  38 + openTransition:{
  39 + type: Boolean,
  40 + default:true,
  41 + },
  42 + viewHeight:{
  43 + type:Number,
  44 + default() {
  45 + return uni.getSystemInfoSync().windowHeight;
  46 + }
  47 + }
  48 + },
  49 + watch:{
  50 + scrollTop(val){
  51 + this.onScroll(val)
  52 + }
  53 + },
  54 + data(){
  55 + return {
  56 + uid:'',
  57 + loadImg:false,
  58 + showImg:false,
  59 + isLoadError:false,
  60 + showTransition:false
  61 + }
  62 + },
  63 + methods:{
  64 + init(){
  65 + this.uid = 'uid-' + generateUUID();
  66 + this.$nextTick(this.onScroll)
  67 + },
  68 + handleImgLoad(e){
  69 + // console.log('success');
  70 + this.showImg = true;
  71 + // this.$nextTick(function(){
  72 + // this.showTransition = true
  73 + // })
  74 + setTimeout(()=>{
  75 + this.showTransition = true
  76 + },50)
  77 + },
  78 + handleImgError(e){
  79 + // console.log('fail');
  80 + this.isLoadError = true;
  81 + },
  82 + onScroll(scrollTop){
  83 + // 加载ing时才执行滚动监听判断是否可加载
  84 + if(this.loadImg || this.isLoadError) return;
  85 + const id = this.uid
  86 + const query = uni.createSelectorQuery().in(this);
  87 + query.select('#'+id).boundingClientRect(data => {
  88 + if(!data) return;
  89 + if(data.top - this.viewHeight<0){
  90 + this.loadImg = true;
  91 + }
  92 + }).exec()
  93 + },
  94 + },
  95 + mounted() {
  96 + this.init()
  97 + }
  98 +}
  99 +</script>
  100 +
  101 +<style scoped>
  102 + /* 官方优化图片tips */
  103 + image{
  104 + will-change: transform
  105 + }
  106 + /* 渐变过渡效果处理 */
  107 + image.origin-img{
  108 + width: 100%;
  109 + height: 100%;
  110 + opacity: 0.3;
  111 + }
  112 + image.origin-img.show-transition{
  113 + transition: opacity 1.2s;
  114 + opacity: 1;
  115 + }
  116 + image.origin-img.no-transition{
  117 + opacity: 1;
  118 + }
  119 + /* 加载失败、加载中的占位图样式控制 */
  120 + .loadfail-img{
  121 + height: 100%;
  122 + background: url('~@/static/easy-loadimage/loadfail.png') no-repeat center;
  123 + background-size: 50%;
  124 + }
  125 + .loading-img{
  126 + height: 100%;
  127 + }
  128 + /* 转圈 */
  129 + .spin-circle{
  130 + background: url('~@/static/easy-loadimage/loading.gif') no-repeat center;
  131 + background-size: 100rpx;
  132 + }
  133 + /* 动态灰色若隐若现 */
  134 + .looming-gray{
  135 + animation: looming-gray 1s infinite linear;
  136 + background-color: #e3e3e3;
  137 + }
  138 + @keyframes looming-gray{
  139 + 0% {background-color:#e3e3e3aa;}
  140 + 50% {background-color:#e3e3e3;}
  141 + 100% {background-color:#e3e3e3aa;}
  142 + }
  143 + /* 骨架屏1 */
  144 + .skeleton-1{
  145 + background-color: #e3e3e3;
  146 + background-image: linear-gradient(100deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0) 80%);
  147 + background-size: 100rpx 100%;
  148 + background-repeat: repeat-y;
  149 + background-position:0 0;
  150 + animation: skeleton-1 .6s infinite;
  151 + }
  152 + @keyframes skeleton-1 {
  153 + to {
  154 + background-position: 200% 0;
  155 + }
  156 + }
  157 + /* 骨架屏2 */
  158 + .skeleton-2{
  159 + background-image: linear-gradient(-90deg, #fefefe 0%, #e6e6e6 50%,#fefefe 100%);
  160 + background-size: 400% 400%;
  161 + background-position:0 0;
  162 + animation: skeleton-2 1.2s ease-in-out infinite;
  163 + }
  164 + @keyframes skeleton-2{
  165 + to {
  166 + background-position: -135% 0;
  167 + }
  168 + }
  169 +</style>
  170 +
... ...
src/pages/cart/cart.vue
... ... @@ -8,7 +8,7 @@
8 8 <view class="cardHeader">
9 9 <view
10 10 v-bind:class="pIsoPen? 'partentChecked' : 'partentCheck'"
11   - @tap="pChange(pIsoPen)"
  11 + @touchstart="pChange(pIsoPen)"
12 12 >
13 13 <span class="correct"></span>
14 14 </view>
... ... @@ -21,12 +21,12 @@
21 21 <view
22 22 class="cardBody"
23 23 v-for="(item,index) in cartList"
24   - :key="item.cart_id"
  24 + :key="index"
25 25 @longpress="delCart(item.cart_id,index)"
26 26 >
27 27 <view
28 28 v-bind:class="childIsOpen[index]? 'partentChecked':'partentCheck'"
29   - @tap="Change(childIsOpen[index],index)"
  29 + @touchstart="Change(childIsOpen[index],index)"
30 30 >
31 31 <span class="correct"></span>
32 32 </view>
... ... @@ -47,11 +47,10 @@
47 47 @tap="toGoods(item.pid,item.sk_id)"
48 48 >{{item.p_name}}</view>
49 49 <!-- <view class="describ"> -->
50   - <uni-collapse accordion="true">
  50 + <uni-collapse accordion="true" style="justify-content: space-around;width: 196px;">
51 51 <uni-collapse-item
52 52 showAnimation='true'
53   - :title="item.tag.prod_tag_fun[0].label+'/'+item.tag.prod_tag_fun[1].label+'/'+item.tag.prod_tag_fun[2].label+'...' || '暂无'"
54   - >
  53 + :title="item.tag.prod_tag_fun[0].label&&item.tag.prod_tag_fun[1].label?item.tag.prod_tag_fun[0].label+'/'+item.tag.prod_tag_fun[1].label+'...':'暂无数据'">
55 54 <text class="describ">
56 55 <block
57 56 v-for="tag in item.tag.prod_tag_fun"
... ... @@ -127,6 +126,7 @@ export default {
127 126  
128 127 cartList() {
129 128 // console.log('cart-list', this.$store.state.cart.cartList);
  129 + this.totalPrice=0
130 130 return this.$store.state.cart.cartList
131 131 },
132 132 childIsOpen() {
... ... @@ -268,24 +268,24 @@ export default {
268 268 // console.log('delcart------>cart_id',cart_id)
269 269 // console.log('cartlist====>delcart',this.$store.state.cart.cartList)
270 270 // console.log('delcart======>index',index)
271   - const uid = this.$store.state.user.userInfo.uid
272   - const openid = this.$store.state.user.userInfo.openid
273   - uni.showModal({
274   - title: '是否删除该商品',
275   - // content: '是否删除该商品',
276   - success: function (res) {
277   - if (res.confirm) {
278   - // this.$store.state.cart.cartList.splice(index,1)
279   - store.dispatch('cart/delCart', {
280   - uid: uid,
281   - openid: openid,
282   - cart_id: cart_id, // 要修改的购物车id
283   - arg: index, // 由于action 传参是能接收两参数,因此将index放入对象
284   - })
285   - console.log('用户点击确定')
286   - }
287   - },
288   - })
  271 + uni.showModal({
  272 + title: '是否删除该商品',
  273 + // content: '是否删除该商品',
  274 + success: function (res) {
  275 + if (res.confirm) {
  276 + if (this.childIsOpen[index]) {
  277 + this.totalPrice = this.totalPrice - (this.$store.state.cart.cartList[index].nowPrice*this.$store.state.cart.cartList[index].num)
  278 + }
  279 + console.log('index===>',index)
  280 + store.dispatch('cart/delCart', {
  281 + uid: this.$store.state.user.userInfo.uid,
  282 + openid: this.$store.state.user.userInfo.openid,
  283 + cart_id: cart_id, // 要修改的购物车id
  284 + arg: index, // 由于action 传参是能接收两参数,因此将index放入对象
  285 + })
  286 + }
  287 + }.bind(this),
  288 + })
289 289 },
290 290 },
291 291 }
... ... @@ -308,14 +308,14 @@ export default {
308 308 border-radius: 22px;
309 309 border: 1px solid #cfcfcf;
310 310 background-color: #ffffff;
311   - margin: 6px;
  311 + margin: 24rpx 12rpx 24rpx 24rpx;
312 312 }
313 313 .partentChecked {
314 314 width: 18px;
315 315 height: 18px;
316 316 border-radius: 22px;
317 317 background-color: #ff6b4a;
318   - margin: 6px;
  318 + margin: 24rpx 12rpx 24rpx 24rpx;
319 319 .correct {
320 320 display: inline-block;
321 321 position: relative;
... ...
src/pages/index/index.vue
... ... @@ -84,6 +84,12 @@
84 84 data-format="Object"
85 85 ></HMfilterDropdown>
86 86 <!-- 商品列表 -->
  87 +<!-- <scroll-view
  88 + enable-flex
  89 + @scrolltolower="handleScrolltolower"
  90 + scroll-y
  91 + style="height: 1000px;margin-bottom: 20px;"
  92 + > -->
87 93 <view class="goods-list">
88 94 <view class="product-list">
89 95 <view
... ... @@ -91,11 +97,12 @@
91 97 v-for="(goods) in goodsList"
92 98 :key="goods.id"
93 99 >
94   - <Card :goods="goods"></Card>
  100 + <Card :goods="goods" :scrollTop="scrollTop" :viewHeight="viewHeight"></Card>
95 101 </view>
96 102 </view>
97 103 <view class="loading-text">{{loadingText}}</view>
98 104 </view>
  105 + <!-- </scroll-view> -->
99 106 </view>
100 107 </view>
101 108 </view>
... ... @@ -121,8 +128,16 @@ export default {
121 128 filterDropdownValue: [],
122 129 filterData: [],
123 130 searchText: '',
  131 + scrollTop: 0,
  132 + viewHeight: uni.getSystemInfoSync().windowHeight,
124 133 }
125 134 },
  135 + onPageScroll({scrollTop}) {
  136 + // 传入scrollTop值并触发所有easy-loadimage组件下的滚动监听事件
  137 +
  138 + this.scrollTop = scrollTop;
  139 + console.log('pagescroll====>',this.viewHeight)
  140 + },
126 141 computed: {
127 142 goodsList () {
128 143 // 也可以从 getters 获取
... ...
src/pages/user/user.vue
... ... @@ -36,10 +36,16 @@
36 36 <button @tap="chatOur(2)">客服2</button>
37 37 </view>
38 38 </uni-popup>
39   - <view
40   - v-if="isAuth"
41   - class="content"
42   - >
  39 +<!-- <scroll-view
  40 + enable-flex
  41 + @scrolltolower="handleScrolltolower"
  42 + scroll-y
  43 + style="height: 1000px;"
  44 + > -->
  45 + <view
  46 + v-if="isAuth"
  47 + class="content"
  48 + >
43 49 <view class="userInfo">
44 50 <view class="info">
45 51 <image
... ... @@ -192,24 +198,26 @@
192 198 </view>
193 199 <!-- 商品列表 -->
194 200 <view class="goods-list">
195   - <scroll-view
  201 +<!-- <scroll-view
196 202 enable-flex
197 203 @scrolltolower="handleScrolltolower"
198 204 scroll-y
199 205 class="product-list"
200   - >
  206 + > -->
  207 + <view class="product-list">
201 208 <view
202 209 class="product"
203 210 v-for="(item, index) in userRecommandList"
204 211 :key="index"
205 212 >
206   - <Card :goods="item"></Card>
  213 + <Card :goods="item" :scrollTop="scrollTop" :viewHeight="viewHeight"></Card>
207 214 </view>
208   - </scroll-view>
  215 + </view>
  216 + <!-- </scroll-view> -->
209 217 <view class="loading-text">{{loadingText}}</view>
210 218 </view>
211 219 </view>
212   - </view>
  220 + </view>
213 221 <view
214 222 v-else
215 223 class="auth"
... ... @@ -224,6 +232,7 @@
224 232 @getuserinfo="onGotUserInfo"
225 233 >授权登陆</button>
226 234 </view>
  235 + <!-- </scroll-view> -->
227 236 </view>
228 237 </template>
229 238  
... ... @@ -241,9 +250,16 @@ export default {
241 250 return {
242 251 isAuth: true, // 是否显示授权页面,
243 252 pagesnum: 1, // 分页请求初始值
244   - whichTap: 0 // 弹窗渲染选择条件
  253 + whichTap: 0 ,// 弹窗渲染选择条件
  254 + loadingText: '到底了',
  255 + scrollTop: 0,
  256 + viewHeight: uni.getSystemInfoSync().windowHeight,
245 257 }
246 258 },
  259 + onPageScroll({scrollTop}) {
  260 + // 传入scrollTop值并触发所有easy-loadimage组件下的滚动监听事件
  261 + this.scrollTop = scrollTop;
  262 + },
247 263 onLoad() {
248 264 // 判断是否授权
249 265 uni.getSetting({
... ... @@ -262,6 +278,15 @@ export default {
262 278 page: this.pagesnum
263 279 })
264 280 },
  281 + onReachBottom() {
  282 + // console.log('usr-my',this.$store.state.user.userInfo)
  283 + this.pagesnum++
  284 + store.dispatch('userRecommand/getRecommandList', {
  285 + uid: this.$store.state.user.userInfo.uid,
  286 + openid: this.$store.state.user.userInfo.openid,
  287 + page: this.pagesnum
  288 + })
  289 + },
265 290 computed: {
266 291 nickName() {
267 292 return this.$store.state.user.userInfo.nickName
... ... @@ -332,15 +357,6 @@ export default {
332 357 uni.navigateTo({
333 358 url: '../addOpticsData/addOpticsData'
334 359 })
335   - },
336   - handleScrolltolower() {
337   - // console.log('usr-my',this.$store.state.user.userInfo)
338   - this.pagesnum++
339   - store.dispatch('userRecommand/getRecommandList', {
340   - uid: this.$store.state.user.userInfo.uid,
341   - openid: this.$store.state.user.userInfo.openid,
342   - page: this.pagesnum
343   - })
344 360 }
345 361 }
346 362 }
... ... @@ -581,7 +597,6 @@ export default {
581 597 display: flex;
582 598 justify-content: space-between;
583 599 flex-wrap: wrap;
584   - height: 400px;
585 600 .product {
586 601 width: 48%;
587 602 margin: 0 0 20rpx 0;
... ...
src/static/easy-loadimage/loadfail.png

3.42 KB

src/static/easy-loadimage/loading.gif

16.9 KB

src/store/modules/index.js
... ... @@ -9,7 +9,7 @@
9 9  
10 10 const state = {
11 11 categoryList: [],
12   - list: [],
  12 + list: []
13 13 };
14 14  
15 15 const mutations = {
... ... @@ -18,7 +18,7 @@ const mutations = {
18 18 },
19 19 CATEGORY: (state, categoryList) => {
20 20 state.categoryList = categoryList;
21   - },
  21 + }
22 22 };
23 23  
24 24 const actions = {
... ... @@ -84,7 +84,7 @@ const actions = {
84 84 console.log("complete status === > ", res);
85 85 },
86 86 })
87   - }
  87 + },
88 88 };
89 89  
90 90 export default {
... ...
src/store/modules/userRecommand.js
... ... @@ -23,7 +23,8 @@ const actions = {
23 23 url: recommandList,
24 24 data: param,
25 25 success: (res) => {
26   - console.log(res.data.data)
  26 + console.log('ReccomandList请求结果',res.data)
  27 + // console.log(res.data.data)
27 28 // const Res={...res.data.data.list,...data.data.list}
28 29 const data = res.data.data
29 30 for (let index = 0; index < data.length; index++) {
... ...