Authored by 陈轩

sort productList

1 <div id="product-list"> 1 <div id="product-list">
2 - <Sort></Sort>  
3 - <List url="/product/list" :query='{a:1}'></List> 2 + <Sort :config.once="sortConfig" :val="sort">
  3 + </Sort>
  4 + <List :data="productList"></List>
4 <Drawer> 5 <Drawer>
5 <Filter></Filter> 6 <Filter></Filter>
6 </Drawer> 7 </Drawer>
7 -</div>  
  8 +</div>
  9 +<script>
  10 + var sortConfig = [
  11 + {txt: '默认', val: 1 },
  12 + {txt: '最新', val: 2 },
  13 + {type: 'updown', txt: '价格', val: [3, 4] }, //[up, down]
  14 + {type: 'updown', txt: '折扣', val: [5, 6] }
  15 +];
  16 +</script>
1 const Vue = require('yoho-vue'); 1 const Vue = require('yoho-vue');
2 const lazyload = require('yoho-vue-lazyload'); 2 const lazyload = require('yoho-vue-lazyload');
3 const infinitScroll = require('yoho-vue-infinite-scroll'); 3 const infinitScroll = require('yoho-vue-infinite-scroll');
  4 +const bus = require('common/vue-bus');
4 const sort = require('product/sort.vue'); 5 const sort = require('product/sort.vue');
5 const list = require('product/list.vue'); 6 const list = require('product/list.vue');
6 const drawer = require('product/drawer.vue'); 7 const drawer = require('product/drawer.vue');
@@ -11,9 +12,104 @@ Vue.use(infinitScroll); @@ -11,9 +12,104 @@ Vue.use(infinitScroll);
11 12
12 require('common/vue-filter'); 13 require('common/vue-filter');
13 14
14 -new Vue({ 15 +const app = new Vue({
15 el: '#product-list', 16 el: '#product-list',
  17 + data: function() {
  18 + return {
  19 + sortConfig: global.sortConfig,
  20 + filterConfig: [],
  21 +
  22 + // query
  23 + url: 'list',
  24 + sort: 3,
  25 + filter: [],
  26 + page: 0, // page= 0 未搜索, 1 并且productList.length =0 没有数据, page = page_total 全部加载完
  27 + totalPage: 0,
  28 +
  29 + // 产品列表
  30 + productList: [],
  31 +
  32 + // state:
  33 + inSearching: false
  34 + };
  35 + },
16 components: { 36 components: {
17 - list, sort, filter, drawer 37 + list,
  38 + sort,
  39 + filter,
  40 + drawer
  41 + },
  42 + methods: {
  43 + search: function() {
  44 + if (this.inSearching) {
  45 + return;
  46 + }
  47 + const self = this;
  48 +
  49 + this.inSearching = true;
  50 + $.post(this.url, {
  51 + sort: this.sort,
  52 + filter: this.filter,
  53 + page: this.page
  54 + })
  55 + .done(res => {
  56 + self.$set('productList', self.productList.concat(res.data.productList));
  57 + })
  58 + .fail(error => {
  59 + self.page--;
  60 + })
  61 + .always(()=>{
  62 + self.inSearching = false;
  63 + });
  64 + },
  65 +
  66 + pageState: function() {
  67 +
  68 + },
  69 +
  70 + /**
  71 + *
  72 + */
  73 + research: function() {
  74 +
  75 + }
  76 + },
  77 + watch: {
  78 + /* sort 和 filter 改变 都会触发 重新搜索 (想象成清空所有分页) */
  79 + sort: function() {
  80 + this.page = 0;
  81 + },
  82 + filter: function() {
  83 + this.page = 0;
  84 + },
  85 +
  86 + page: function(newVal, oldVal) {
  87 + if (newVal === 0) {
  88 + // when research
  89 + this.$set('productList', []);
  90 + this.search();
  91 + } else if (newVal > oldVal && newVal > this.totalPage) {
  92 + // when fetch
  93 + this.search();
  94 + }
  95 + }
  96 + },
  97 +
  98 + created: function() {
  99 + this.search();
18 } 100 }
19 }); 101 });
  102 +
  103 +bus.$on('list.paging', function() {
  104 + app.page++;
  105 +});
  106 +
  107 +bus.$on('sort.change', function({ val}) {
  108 + console.log(val);
  109 + app.sort = val;
  110 +});
  111 +
  112 +bus.$on('filter.change', function({ val}) {
  113 + console.log(val);
  114 + app.filter = val;
  115 +});
1 <template> 1 <template>
2 <div class="goods-box" v-infinite-scroll="fetch()" infinite-scroll-disable="disableFetch"> 2 <div class="goods-box" v-infinite-scroll="fetch()" infinite-scroll-disable="disableFetch">
3 <ul class="cardlist card-large clearfix"> 3 <ul class="cardlist card-large clearfix">
4 - <li class="card" v-for="item in products"> 4 + <li class="card" v-for="item in data">
5 <div class="card-pic"> 5 <div class="card-pic">
6 <a href=""> 6 <a href="">
7 <img v-lazy="item.goodsList[0].imagesUrl | resize 372 499" alt="{{item.productName}}"> 7 <img v-lazy="item.goodsList[0].imagesUrl | resize 372 499" alt="{{item.productName}}">
@@ -21,75 +21,21 @@ @@ -21,75 +21,21 @@
21 </div> 21 </div>
22 </template> 22 </template>
23 <script> 23 <script>
24 -let $ = require('yoho-jquery');  
25 -  
26 -/**  
27 - * @example  
28 - * <List url='' :query='{}' disable-fetch></List>  
29 - * <List :init-data='{}'></List>  
30 - */ 24 +let bus = require('common/vue-bus');
31 25
32 module.exports = { 26 module.exports = {
33 props: { 27 props: {
34 -  
35 - /* 请求地址 */  
36 - url: {  
37 - type: String,  
38 - required: true  
39 - },  
40 -  
41 - /* 初始数据, 应该只单次绑定, 然后fetch数据全靠url */  
42 - initData: Array,  
43 -  
44 - /* 请求参数 */  
45 - query: Object,  
46 -  
47 /* 开启滚动加载 */ 28 /* 开启滚动加载 */
48 - disableFetch: Boolean  
49 - },  
50 - data: function() {  
51 - return {  
52 - state: {  
53 - curPage: 0,  
54 - totalPage: 10  
55 - },  
56 - products: [],  
57 - inLoading: false,  
58 - atEnd: false  
59 - }; 29 + disableFetch: Boolean,
  30 +
  31 + //数据
  32 + data: Array
60 }, 33 },
61 methods: { 34 methods: {
62 fetch: function() { 35 fetch: function() {
63 - if (this.atEnd) {  
64 - return;  
65 - }  
66 - let self = this;  
67 -  
68 - this.state.curPage++;  
69 - this.inLoading = true;  
70 - $.ajax({  
71 - url: this.url,  
72 - type: 'POST',  
73 - })  
74 - .done(result => {  
75 - self.$set('products', self.products.concat(result.data.productList));  
76 - })  
77 - .always(() => {  
78 - self.inLoading = false;  
79 - self.atEnd = self.state.curPage === self.state.totalPage;  
80 - });  
81 -  
82 - }  
83 - },  
84 - created: function() {  
85 - // 有初始数据,用初始数据  
86 - if (this.initData) {  
87 - this.$set('products', this.products.concat(this.initData));  
88 - this.atEnd = true;  
89 - } else if (this.url) {  
90 - this.fetch(); 36 + bus.$emit('list.paging');
91 } 37 }
92 - }, 38 + }
93 }; 39 };
94 </script> 40 </script>
95 <style> 41 <style>
1 <template> 1 <template>
2 <ul class="sort-navs clearfix"> 2 <ul class="sort-navs clearfix">
3 - <li class="sort-item active"><span>默认</span></li>  
4 - <li class="sort-item">  
5 - <span class="sort-name">最新</span>  
6 - <span class="sort-icon">  
7 - <i class="icon icon-sort-asc"></i>  
8 - <i class="icon icon-sort-desc"></i>  
9 - </span>  
10 - </li>  
11 - <li class="sort-item">  
12 - <span class="sort-name">价格</span>  
13 - </li>  
14 - <li class="sort-item">  
15 - <span class="sort-name">折扣</span>  
16 - <span class="sort-icon">  
17 - <i class="icon icon-sort-asc"></i>  
18 - <i class="icon icon-sort-desc"></i>  
19 - </span>  
20 - </li> 3 + <template v-for="item in config">
  4 + <simple v-if="(item.type || 'simple') === 'simple'" :txt="item.txt" :val="item.val">
  5 + </simple>
  6 + <updown v-if="item.type === 'updown'" :txt="item.txt" :vals="item.val">
  7 + </updown>
  8 + </template>
21 </ul> 9 </ul>
22 </template> 10 </template>
23 <script> 11 <script>
  12 +const $ = require('yoho-jquery');
  13 +const bus = require('common/vue-bus');
  14 +const simple = require('./sort/simple.vue');
  15 +const updown = require('./sort/updown.vue');
  16 +
24 module.exports = { 17 module.exports = {
  18 + props: {
  19 + /**
  20 + * sort 配置
  21 + * @type {Array} [{type, txt, val}]
  22 + * type: 类型 simple, updown
  23 + * txt: 文字,
  24 + * val: 值
  25 + */
  26 + config: Array,
25 27
  28 + //初始值 可以进行双向绑定
  29 + val: Number
  30 + },
  31 + components: {
  32 + simple,
  33 + updown
  34 + },
  35 + methods: {},
  36 + watch: {
  37 + 'val': function(newVal, oldVal) {
  38 + bus.$emit('sort.change', {
  39 + val: newVal,
  40 + ref: this._uid
  41 + });
  42 + }
  43 + }
26 }; 44 };
27 </script> 45 </script>
28 <style> 46 <style>
@@ -41,7 +59,6 @@ module.exports = { @@ -41,7 +59,6 @@ module.exports = {
41 width: 25%; 59 width: 25%;
42 float: left; 60 float: left;
43 text-align: center; 61 text-align: center;
44 -  
45 &:after { 62 &:after {
46 content: "|"; 63 content: "|";
47 position: absolute; 64 position: absolute;
@@ -52,15 +69,12 @@ module.exports = { @@ -52,15 +69,12 @@ module.exports = {
52 &:last-of-type:after { 69 &:last-of-type:after {
53 display: none; 70 display: none;
54 } 71 }
55 -  
56 .sort-name { 72 .sort-name {
57 font-size: 28px; 73 font-size: 28px;
58 } 74 }
59 -  
60 .sort-icon { 75 .sort-icon {
61 position: relative; 76 position: relative;
62 margin-left: 10px; 77 margin-left: 10px;
63 -  
64 .icon-sort-asc, 78 .icon-sort-asc,
65 .icon-sort-desc { 79 .icon-sort-desc {
66 position: absolute; 80 position: absolute;
@@ -68,7 +82,6 @@ module.exports = { @@ -68,7 +82,6 @@ module.exports = {
68 top: 0; 82 top: 0;
69 } 83 }
70 } 84 }
71 -  
72 &.active { 85 &.active {
73 color: $black; 86 color: $black;
74 } 87 }
  1 +<template>
  2 + <li class="sort-item" :class="active" @click="click">
  3 + <span class="sort-name">{{txt}}</span>
  4 + </li>
  5 +</template>
  6 +<script>
  7 +module.exports = {
  8 + props: ['txt', 'val'],
  9 + computed: {
  10 + active: function() {
  11 + if (this.val === this.$parent.val) {
  12 + return 'active';
  13 + }
  14 + }
  15 + },
  16 + methods: {
  17 + click: function() {
  18 + this.$parent.val = this.val;
  19 + }
  20 + }
  21 +};
  22 +</script>
  1 +<template>
  2 + <li class="sort-item" :class="active" @click="clickHandler">
  3 + <span class="sort-name">{{txt}}</span>
  4 + <span class="sort-icon">
  5 + <i class="icon icon-sort-asc" :class="{active: $parent.val === vals[0]}"></i>
  6 + <i class="icon icon-sort-desc" :class="{active: $parent.val === vals[1]}"></i>
  7 + </span>
  8 + </li>
  9 +</template>
  10 +<style>
  11 +.sort-item .icon {
  12 + color: #b0b0b0;
  13 + &.active {
  14 + color: #000;
  15 + }
  16 +}
  17 +</style>
  18 +<script>
  19 +module.exports = {
  20 + props: {
  21 + txt: String,
  22 + vals: Array //[asc, desc]
  23 + },
  24 + data: function() {
  25 + return {};
  26 + },
  27 + computed: {
  28 + active: function() {
  29 + const index = this.vals.indexOf(this.$parent.val);
  30 +
  31 + if (index >= 0) {
  32 + return {
  33 + 'active': true,
  34 + };
  35 + }
  36 + }
  37 + },
  38 + methods: {
  39 + clickHandler: function() {
  40 + let index = this.vals.indexOf(this.$parent.val);
  41 +
  42 + if (index === -1) {
  43 + this.$parent.val = this.vals[0];
  44 + } else {
  45 + index = index === 0 ? 1 : 0;
  46 + this.$parent.val = this.vals[index];
  47 + }
  48 + }
  49 + }
  50 +};
  51 +</script>