Showing
8 changed files
with
415 additions
and
116 deletions
@@ -18,9 +18,9 @@ module.exports = { | @@ -18,9 +18,9 @@ module.exports = { | ||
18 | app_type: 1 | 18 | app_type: 1 |
19 | }, | 19 | }, |
20 | domains: { | 20 | domains: { |
21 | - api: 'http://api-test2.yohops.com:9999/', | ||
22 | - service: 'http://service-test2.yohops.com:9999/', | ||
23 | - singleApi: 'http://api-test2.yohops.com:9999/', | 21 | + api: 'http://api-test3.yohops.com:9999/', |
22 | + service: 'http://service-test3.yohops.com:9999/', | ||
23 | + singleApi: 'http://api-test3.yohops.com:9999/', | ||
24 | 24 | ||
25 | // api: 'http://api-test3.yohops.com:9999/', | 25 | // api: 'http://api-test3.yohops.com:9999/', |
26 | // service: 'http://service-test3.yohops.com:9999/', | 26 | // service: 'http://service-test3.yohops.com:9999/', |
@@ -9,15 +9,25 @@ | @@ -9,15 +9,25 @@ | ||
9 | </ul> | 9 | </ul> |
10 | <div class="sub-level-container"> | 10 | <div class="sub-level-container"> |
11 | <ul class="sub-level"> | 11 | <ul class="sub-level"> |
12 | - <li class="ellipsis"> | ||
13 | - <a v-if="jump" href="/product/list?sort={{rightAll.sortId || '' }}&sort_name=全部{{rightAll.categoryName || ''}}&gender={{gender}}">全部{{rightAll.categoryName}}</a> | ||
14 | - <a v-else @click="noJumpReturn(rightAll.sortId, '全部' + rightAll.categoryName)">全部{{rightAll.categoryName}}</a> | 12 | + <li :class="{'sub-checked': rightAll.checked}"> |
13 | + <div class="block ellipsis"> | ||
14 | + <a v-if="jump" href="/product/list?sort={{rightAll.sortId || '' }}&sort_name=全部{{rightAll.categoryName || ''}}&gender={{gender}}">全部{{rightAll.categoryName}}</a> | ||
15 | + <a v-else @click="noJumpReturn(rightAll.sortId, '全部' + rightAll.categoryName, true)">全部{{rightAll.categoryName}}</a> | ||
16 | + </div> | ||
17 | + <div class="checked"> | ||
18 | + <i class="icon icon-check"></i> | ||
19 | + </div> | ||
15 | </li> | 20 | </li> |
16 | </ul> | 21 | </ul> |
17 | <ul class="sub-level"> | 22 | <ul class="sub-level"> |
18 | - <li v-for="sub in cateNavRightData" class="ellipsis"> | ||
19 | - <a v-if="jump" href="/product/list?sort={{sub.relation_parameter.sort}}&sort_name={{sub.category_name}}&gender={{gender}}">{{sub.category_name}}</a> | ||
20 | - <a v-else @click="noJumpReturn(sub.relation_parameter.sort, sub.category_name)">{{sub.category_name}}</a> | 23 | + <li v-for="sub in cateNavRightData" :class="{'sub-checked': sub.checked}"> |
24 | + <div class="block ellipsis"> | ||
25 | + <a v-if="jump" href="/product/list?sort={{sub.relation_parameter.sort}}&sort_name={{sub.category_name}}&gender={{gender}}">{{sub.category_name}}</a> | ||
26 | + <a v-else @click="noJumpReturn(sub.relation_parameter.sort, sub.category_name)">{{sub.category_name}}</a> | ||
27 | + </div> | ||
28 | + <div class="checked"> | ||
29 | + <i class="icon icon-check"></i> | ||
30 | + </div> | ||
21 | </li> | 31 | </li> |
22 | </ul> | 32 | </ul> |
23 | </div> | 33 | </div> |
@@ -184,30 +194,44 @@ | @@ -184,30 +194,44 @@ | ||
184 | line-height: 88px; | 194 | line-height: 88px; |
185 | border-bottom: 1px solid #e6e6e6; | 195 | border-bottom: 1px solid #e6e6e6; |
186 | padding-left: 30px; | 196 | padding-left: 30px; |
187 | - margin-right: 30px; | ||
188 | user-select: none; | 197 | user-select: none; |
189 | white-space: nowrap; | 198 | white-space: nowrap; |
190 | overflow-y: auto; | 199 | overflow-y: auto; |
200 | + display: flex; | ||
191 | 201 | ||
192 | &.highlight { | 202 | &.highlight { |
193 | background: #eee; | 203 | background: #eee; |
194 | } | 204 | } |
195 | 205 | ||
206 | + &.sub-checked { | ||
207 | + .icon { | ||
208 | + display: inline !important; | ||
209 | + } | ||
210 | + } | ||
211 | + | ||
196 | &:hover { | 212 | &:hover { |
197 | background-color: #efefef; | 213 | background-color: #efefef; |
198 | } | 214 | } |
199 | - } | ||
200 | 215 | ||
201 | - a { | ||
202 | - position: absolute; | ||
203 | - top: 0; | ||
204 | - right: 0; | ||
205 | - bottom: 0; | ||
206 | - left: 20px; | ||
207 | - display: inline; | ||
208 | - color: #b0b0b0; | ||
209 | - overflow: hidden; | ||
210 | - text-overflow: ellipsis; | 216 | + .block { |
217 | + flex: 1; | ||
218 | + } | ||
219 | + | ||
220 | + .checked { | ||
221 | + width: 100px; | ||
222 | + text-align: center; | ||
223 | + color: #000; | ||
224 | + | ||
225 | + .icon { | ||
226 | + display: none; | ||
227 | + } | ||
228 | + } | ||
229 | + | ||
230 | + a { | ||
231 | + color: #b0b0b0; | ||
232 | + display: block; | ||
233 | + width: 100%; | ||
234 | + } | ||
211 | } | 235 | } |
212 | } | 236 | } |
213 | } | 237 | } |
@@ -225,6 +249,12 @@ | @@ -225,6 +249,12 @@ | ||
225 | }, | 249 | }, |
226 | gender: { | 250 | gender: { |
227 | type: String | 251 | type: String |
252 | + }, | ||
253 | + value: { | ||
254 | + type: Array, | ||
255 | + default() { | ||
256 | + return []; | ||
257 | + } | ||
228 | } | 258 | } |
229 | }, | 259 | }, |
230 | data() { | 260 | data() { |
@@ -232,10 +262,15 @@ | @@ -232,10 +262,15 @@ | ||
232 | cateNavLeftData: [], // 左侧分类数据 | 262 | cateNavLeftData: [], // 左侧分类数据 |
233 | cateNavRightData: [], // 右侧分类数据 | 263 | cateNavRightData: [], // 右侧分类数据 |
234 | leftcurrent: 0, // 标记当前左侧选中条目 | 264 | leftcurrent: 0, // 标记当前左侧选中条目 |
235 | - rightAll: {} // 全部XX | 265 | + rightAll: {}, // 全部XX |
266 | + currentValue: this.value | ||
236 | }; | 267 | }; |
237 | }, | 268 | }, |
238 | watch: { | 269 | watch: { |
270 | + value(val) { | ||
271 | + this.currentValue = val; | ||
272 | + this.categoryChangeHandler(); | ||
273 | + }, | ||
239 | category() { | 274 | category() { |
240 | this.categoryChangeHandler(); | 275 | this.categoryChangeHandler(); |
241 | } | 276 | } |
@@ -244,17 +279,48 @@ | @@ -244,17 +279,48 @@ | ||
244 | cateNavLeftFun(index, categoryId, categoryName) { | 279 | cateNavLeftFun(index, categoryId, categoryName) { |
245 | this.leftcurrent = index; | 280 | this.leftcurrent = index; |
246 | this.cateNavRightData = this.cateNavLeftData[index].sub; | 281 | this.cateNavRightData = this.cateNavLeftData[index].sub; |
282 | + let allSorts = this.getAllSortId(this.cateNavRightData); | ||
283 | + | ||
247 | this.rightAll = { | 284 | this.rightAll = { |
248 | - sortId: categoryId ? categoryId : '', | ||
249 | - categoryName: categoryName ? categoryName : '' | 285 | + sortId: allSorts, |
286 | + categoryName: categoryName ? categoryName : '', | ||
287 | + checked: this.currentValue.some(cate => { | ||
288 | + return cate.id.toString() === allSorts; | ||
289 | + }) | ||
250 | }; | 290 | }; |
251 | }, | 291 | }, |
252 | 292 | ||
253 | /* 筛选列表使用返回值 */ | 293 | /* 筛选列表使用返回值 */ |
254 | - noJumpReturn(categoryId, categoryName) { | ||
255 | - this.$dispatch('select', { | ||
256 | - id: categoryId, | ||
257 | - name: categoryName | 294 | + noJumpReturn(categoryId, categoryName, isall) { |
295 | + let cateIndex = this.currentValue.findIndex(cate => cate.id.toString() === categoryId); | ||
296 | + | ||
297 | + if (cateIndex >= 0) { | ||
298 | + this.currentValue.splice(cateIndex, 1); | ||
299 | + } else { | ||
300 | + this.currentValue.push({ | ||
301 | + id: categoryId, | ||
302 | + name: categoryName | ||
303 | + }); | ||
304 | + } | ||
305 | + if (isall) { | ||
306 | + this.cateNavRightData.forEach(cate => { | ||
307 | + let cateRmIndex = this.currentValue | ||
308 | + .findIndex(c => c.id.toString() === cate.relation_parameter.sort); | ||
309 | + | ||
310 | + if (cateRmIndex >= 0) { | ||
311 | + this.currentValue.splice(cateRmIndex, 1); | ||
312 | + } | ||
313 | + }); | ||
314 | + } else if (this.rightAll.checked) { | ||
315 | + let cateRmIndex = this.currentValue.findIndex(c => c.id.toString() === this.rightAll.sortId); | ||
316 | + | ||
317 | + if (cateRmIndex >= 0) { | ||
318 | + this.currentValue.splice(cateRmIndex, 1); | ||
319 | + } | ||
320 | + } | ||
321 | + this.$emit('select', { | ||
322 | + value: this.currentValue, | ||
323 | + subType: 'group_sort' | ||
258 | }); | 324 | }); |
259 | }, | 325 | }, |
260 | 326 | ||
@@ -262,17 +328,30 @@ | @@ -262,17 +328,30 @@ | ||
262 | if (!this.category || !this.category.length) { | 328 | if (!this.category || !this.category.length) { |
263 | return; | 329 | return; |
264 | } | 330 | } |
265 | - | ||
266 | this.$set('cateNavLeftData', this.category); | 331 | this.$set('cateNavLeftData', this.category); |
267 | - this.$set('cateNavRightData', this.cateNavLeftData ? this.cateNavLeftData[0].sub : []); | 332 | + let selectLeftCate = this.cateNavLeftData[this.leftcurrent] || {}; |
268 | 333 | ||
269 | - let allSorts = this.cateNavLeftData[0].sub ? | ||
270 | - this.cateNavLeftData[0].sub.map(sort=>sort.relation_parameter.sort).join(',') : ''; | 334 | + this.cateNavRightData = []; |
335 | + this.$nextTick(() => { | ||
336 | + this.$set('cateNavRightData', selectLeftCate.sub); | ||
271 | 337 | ||
272 | - this.$set('rightAll', this.cateNavLeftData ? { | ||
273 | - sortId: allSorts, | ||
274 | - categoryName: this.cateNavLeftData[0].category_name | ||
275 | - } : {}); | 338 | + this.cateNavRightData.forEach(cate => { |
339 | + cate.checked = this.currentValue | ||
340 | + .some(selCate => | ||
341 | + selCate.id.toString() === cate.relation_parameter.sort); | ||
342 | + }); | ||
343 | + | ||
344 | + let allSorts = this.getAllSortId(this.cateNavRightData); | ||
345 | + | ||
346 | + this.$set('rightAll', this.cateNavLeftData ? { | ||
347 | + sortId: allSorts, | ||
348 | + categoryName: selectLeftCate.category_name, | ||
349 | + checked: this.currentValue.some(cate => cate.id.toString() === allSorts) | ||
350 | + } : {}); | ||
351 | + }); | ||
352 | + }, | ||
353 | + getAllSortId(sub) { | ||
354 | + return sub.map(sort=>sort.relation_parameter.sort).join(',') + ','; | ||
276 | } | 355 | } |
277 | }, | 356 | }, |
278 | created() { | 357 | created() { |
1 | <template> | 1 | <template> |
2 | <div class="filter-detail"> | 2 | <div class="filter-detail"> |
3 | - <div class="item" @click="select({id: ''})"> | ||
4 | - <div class="item-inner">所有品牌</div> | ||
5 | - </div> | ||
6 | - <dl v-for="key in orderKeys"> | ||
7 | - <dt class="index" id="{{key}}">{{key}}</dt> | ||
8 | - <dd class="item" v-for="brand in data[key]" :class="{'active': brand.id === val}" @click="select(brand)"> | 3 | + <dl v-for="item in indexData" :key="item.index"> |
4 | + <dt class="index" id="{{item.index}}">{{item.index}}</dt> | ||
5 | + <dd class="item" v-for="brand in currentData[item.index]" :key="brand.id" :class="{'active': brand.checked}" @click="select(brand)"> | ||
9 | <div class="item-inner">{{brand.name}}</div> | 6 | <div class="item-inner">{{brand.name}}</div> |
7 | + <div class="item-check"> | ||
8 | + <i class="icon icon-check"></i> | ||
9 | + </div> | ||
10 | </dd> | 10 | </dd> |
11 | </dl> | 11 | </dl> |
12 | - <index-list :index-list="indexList"></index-list> | 12 | + <index-list class="filter-index-list" :index-list="indexData"></index-list> |
13 | </div> | 13 | </div> |
14 | </template> | 14 | </template> |
15 | <script> | 15 | <script> |
@@ -25,55 +25,82 @@ | @@ -25,55 +25,82 @@ | ||
25 | 25 | ||
26 | module.exports = { | 26 | module.exports = { |
27 | props: { | 27 | props: { |
28 | - val: Number, | ||
29 | data: { | 28 | data: { |
30 | - default: () => { return [];}, | ||
31 | - coerce(data) { | ||
32 | - const res = {}; | ||
33 | - | ||
34 | - $.each(data, (index, brand) => { | ||
35 | - let groupName = brand.alif; | ||
36 | - | ||
37 | - if (!res.hasOwnProperty(groupName)) { | ||
38 | - res[groupName] = []; | ||
39 | - } | ||
40 | - res[groupName].push(brand); | ||
41 | - }); | ||
42 | - return res; | 29 | + type: Array, |
30 | + default() { | ||
31 | + return []; | ||
32 | + } | ||
33 | + }, | ||
34 | + value: { | ||
35 | + type: Array, | ||
36 | + default() { | ||
37 | + return []; | ||
43 | } | 38 | } |
44 | } | 39 | } |
45 | }, | 40 | }, |
46 | data() { | 41 | data() { |
47 | return { | 42 | return { |
48 | - indexList: [] | 43 | + indexData: [], |
44 | + currentData: [], | ||
45 | + currentValue: this.value | ||
49 | }; | 46 | }; |
50 | }, | 47 | }, |
51 | watch: { | 48 | watch: { |
52 | - }, | ||
53 | - methods: { | ||
54 | - select: function(val) { | ||
55 | - this.$dispatch('select', val); | 49 | + value(val) { |
50 | + this.currentValue = val; | ||
51 | + this.renderData(); | ||
56 | } | 52 | } |
57 | }, | 53 | }, |
58 | - computed: { | ||
59 | - orderKeys() { | ||
60 | - let keys = []; | ||
61 | - const self = this; | 54 | + methods: { |
55 | + renderData() { | ||
56 | + const res = {}; | ||
57 | + | ||
58 | + $.each(this.data, (index, brand) => { | ||
59 | + let groupName = brand.alif; | ||
62 | 60 | ||
63 | - keys = Object.keys(this.data).sort(); | ||
64 | - self.$set('indexList', keys.map(k => { | 61 | + if (!res.hasOwnProperty(groupName)) { |
62 | + res[groupName] = []; | ||
63 | + } | ||
64 | + brand.checked = this.currentValue.some(b => b.id === brand.id); | ||
65 | + res[groupName].push(brand); | ||
66 | + }); | ||
67 | + this.currentData = res; | ||
68 | + this.indexData = Object.keys(this.currentData).sort().map(k => { | ||
65 | return { | 69 | return { |
66 | index: k, | 70 | index: k, |
67 | name: k | 71 | name: k |
68 | }; | 72 | }; |
69 | - })); | 73 | + }); |
74 | + }, | ||
75 | + select: function(val) { | ||
76 | + let brandIndex = this.currentValue.findIndex(brand => brand.id === val.id); | ||
70 | 77 | ||
71 | - return keys; | 78 | + if (brandIndex >= 0) { |
79 | + this.currentValue.splice(brandIndex, 1); | ||
80 | + } else { | ||
81 | + this.currentValue.push({ | ||
82 | + id: val.id, | ||
83 | + name: val.name | ||
84 | + }); | ||
85 | + } | ||
86 | + this.$emit('select', { | ||
87 | + value: this.currentValue, | ||
88 | + subType: 'brand' | ||
89 | + }); | ||
72 | } | 90 | } |
73 | }, | 91 | }, |
92 | + created() { | ||
93 | + this.renderData(); | ||
94 | + }, | ||
74 | components: { | 95 | components: { |
75 | indexList | 96 | indexList |
76 | } | 97 | } |
77 | }; | 98 | }; |
78 | 99 | ||
79 | </script> | 100 | </script> |
101 | +<style> | ||
102 | +.filter-index-list { | ||
103 | + top: calc(70 + 20 * 2 + 1)px; | ||
104 | +} | ||
105 | + | ||
106 | +</style> |
1 | <template> | 1 | <template> |
2 | <div class="filter-sub" :class="{'filter-sub-open': isVisible}"> | 2 | <div class="filter-sub" :class="{'filter-sub-open': isVisible}"> |
3 | - <c-header class="filter-sub-header" :title="type | filter-cn '选择'"> | 3 | + <c-header class="filter-sub-header" :title="type | filter-cn "> |
4 | <i class="icon icon-left" slot="left" @click="hide"></i> | 4 | <i class="icon icon-left" slot="left" @click="hide"></i> |
5 | + <button class="btn-clear" slot="right" @click="clear">清空</button> | ||
5 | </c-header> | 6 | </c-header> |
6 | <div class="filter-sub-select"> | 7 | <div class="filter-sub-select"> |
7 | - <brand-filter v-if="type === 'brand'" :data="data" @select="selectItem"></brand-filter> | ||
8 | - <normal-filter v-if="type !== 'brand' && type !== 'group_sort'" :data="data" :type="type" @select="selectItem"></normal-filter> | ||
9 | - <sort-filter class="filter-detail filter-sort" v-if="type === 'group_sort'" :category="data" @select="selectItem"></sort-filter> | 8 | + <brand-filter |
9 | + v-if="subType === 'brand'" | ||
10 | + :data="data" | ||
11 | + :value="currentValue" | ||
12 | + @select="selectItem"></brand-filter> | ||
13 | + <normal-filter | ||
14 | + v-if="subType && subType !== 'brand' && subType !== 'group_sort'" | ||
15 | + :data="data" | ||
16 | + :value="currentValue" | ||
17 | + :type="subType" | ||
18 | + @select="selectItem"></normal-filter> | ||
19 | + <sort-filter class="filter-detail filter-sort" | ||
20 | + v-if="subType === 'group_sort'" | ||
21 | + :value="currentValue" | ||
22 | + :category="data" | ||
23 | + @select="selectItem"></sort-filter> | ||
10 | </div> | 24 | </div> |
11 | </div> | 25 | </div> |
12 | </template> | 26 | </template> |
@@ -18,16 +32,57 @@ | @@ -18,16 +32,57 @@ | ||
18 | 32 | ||
19 | module.exports = { | 33 | module.exports = { |
20 | components: {cHeader, brandFilter, normalFilter, sortFilter}, | 34 | components: {cHeader, brandFilter, normalFilter, sortFilter}, |
21 | - props: ['type', 'data'], | 35 | + props: { |
36 | + type: { | ||
37 | + type: String, | ||
38 | + }, | ||
39 | + data: { | ||
40 | + type: Array, | ||
41 | + default() { | ||
42 | + return []; | ||
43 | + } | ||
44 | + }, | ||
45 | + value: { | ||
46 | + type: Array, | ||
47 | + default() { | ||
48 | + return []; | ||
49 | + } | ||
50 | + }, | ||
51 | + }, | ||
22 | data() { | 52 | data() { |
23 | return { | 53 | return { |
24 | - isVisible: false | 54 | + isVisible: false, |
55 | + subType: this.type, | ||
56 | + currentValue: this.value, | ||
57 | + currentData: this.data | ||
25 | }; | 58 | }; |
26 | }, | 59 | }, |
60 | + watch: { | ||
61 | + value(val) { | ||
62 | + this.currentValue = val; | ||
63 | + }, | ||
64 | + type(val) { | ||
65 | + if (this.currentData.length) { | ||
66 | + this.subType = val; | ||
67 | + } | ||
68 | + }, | ||
69 | + data(val) { | ||
70 | + if (!this.subType) { | ||
71 | + this.subType = this.type; | ||
72 | + } | ||
73 | + this.currentData = val; | ||
74 | + }, | ||
75 | + }, | ||
27 | methods: { | 76 | methods: { |
28 | - selectItem() { | ||
29 | - this.hide(); | ||
30 | - return true; | 77 | + selectItem(params) { |
78 | + this.$emit('select', params); | ||
79 | + }, | ||
80 | + clear() { | ||
81 | + this.currentValue = []; | ||
82 | + this.$emit('select', { | ||
83 | + value: this.currentValue, | ||
84 | + subType: this.type | ||
85 | + }); | ||
31 | }, | 86 | }, |
32 | hide() { | 87 | hide() { |
33 | this.isVisible = false; | 88 | this.isVisible = false; |
@@ -55,43 +110,61 @@ | @@ -55,43 +110,61 @@ | ||
55 | 110 | ||
56 | &.filter-sub-open { | 111 | &.filter-sub-open { |
57 | transform: translate3d(0, 0, 0); | 112 | transform: translate3d(0, 0, 0); |
113 | + box-shadow: 0 0 10px 0 #ccc; | ||
114 | + } | ||
115 | + | ||
116 | + .btn-clear { | ||
117 | + font-size: 32px; | ||
118 | + width: 100px; | ||
58 | } | 119 | } |
59 | } | 120 | } |
60 | 121 | ||
61 | .filter-detail { | 122 | .filter-detail { |
62 | - $w: 30px; | ||
63 | - list-style: none; | ||
64 | - margin: 0; | ||
65 | - padding: 0; | ||
66 | - font-size: 40px; | ||
67 | - color: $grey; | 123 | + -webkit-overflow-scrolling: touch; |
124 | + overflow: scroll; | ||
125 | + height: 100%; | ||
126 | + | ||
68 | .item, | 127 | .item, |
69 | .index { | 128 | .index { |
70 | - margin-left: $w; | ||
71 | - margin-right: $w; | ||
72 | - border-bottom: 1px solid #eee; | 129 | + color: #000; |
130 | + font-size: 28px; | ||
131 | + padding-left: 30px; | ||
132 | + padding-right: 30px; | ||
73 | } | 133 | } |
134 | + | ||
74 | .index { | 135 | .index { |
75 | - font-size: 32px; | ||
76 | - font-weight: bold; | ||
77 | - color: $black; | ||
78 | - height: 60px; | ||
79 | - line-height: 60px; | ||
80 | - } | ||
81 | - .item.active .item-inner { | ||
82 | - color: $black; | 136 | + height: 62px; |
137 | + line-height: 62px; | ||
83 | background-color: #f6f6f6; | 138 | background-color: #f6f6f6; |
84 | } | 139 | } |
85 | - .item-inner { | ||
86 | - margin-left: -$w; | ||
87 | - margin-right: -$w; | ||
88 | - padding: 0 $w; | ||
89 | - font-size: 34px; | ||
90 | - height: 102px; | ||
91 | - line-height: 100px; | ||
92 | - overflow: hidden; | ||
93 | - text-overflow: ellipsis; | ||
94 | - white-space: nowrap; | 140 | + |
141 | + .item { | ||
142 | + height: 82px; | ||
143 | + line-height: 82px; | ||
144 | + display: flex; | ||
145 | + border-bottom: solid 1px #eee; | ||
146 | + | ||
147 | + &.active { | ||
148 | + .item-check { | ||
149 | + display: block; | ||
150 | + } | ||
151 | + } | ||
152 | + | ||
153 | + .item-inner { | ||
154 | + flex: 1; | ||
155 | + text-overflow: ellipsis; | ||
156 | + overflow: hidden; | ||
157 | + white-space: nowrap; | ||
158 | + } | ||
159 | + | ||
160 | + .item-check { | ||
161 | + width: 62px; | ||
162 | + display: none; | ||
163 | + | ||
164 | + i { | ||
165 | + font-weight: bold; | ||
166 | + } | ||
167 | + } | ||
95 | } | 168 | } |
96 | } | 169 | } |
97 | 170 | ||
@@ -110,7 +183,7 @@ | @@ -110,7 +183,7 @@ | ||
110 | .filter-detail { | 183 | .filter-detail { |
111 | height: 100%; | 184 | height: 100%; |
112 | overflow: auto; | 185 | overflow: auto; |
113 | - -webkit-overflow-scrolling : touch; | 186 | + -webkit-overflow-scrolling: touch; |
114 | } | 187 | } |
115 | 188 | ||
116 | .filter-sort { | 189 | .filter-sort { |
@@ -118,9 +191,11 @@ | @@ -118,9 +191,11 @@ | ||
118 | margin-top: 0; | 191 | margin-top: 0; |
119 | height: 100%; | 192 | height: 100%; |
120 | } | 193 | } |
194 | + | ||
121 | .content { | 195 | .content { |
122 | height: 100% !important; | 196 | height: 100% !important; |
123 | } | 197 | } |
198 | + | ||
124 | .sub-level-container { | 199 | .sub-level-container { |
125 | overflow: auto; | 200 | overflow: auto; |
126 | } | 201 | } |
1 | <template> | 1 | <template> |
2 | <div class="filter-detail"> | 2 | <div class="filter-detail"> |
3 | - <div class="item"> | ||
4 | - <div class="item-inner" @click="select({id:''})">{{type | filter-cn '所有'}}</div> | ||
5 | - </div> | ||
6 | - <div class="item" v-for="item in data" :class="{active: item.id === val}" @click="select(item)"> | 3 | + <div class="item" v-for="item in currentData" :key="item.id" :class="{active: item.checked}" @click="select(item)"> |
7 | <div class="item-inner"> | 4 | <div class="item-inner"> |
8 | {{item.name}} | 5 | {{item.name}} |
9 | </div> | 6 | </div> |
7 | + <div class="item-check"> | ||
8 | + <i class="icon icon-check"></i> | ||
9 | + </div> | ||
10 | </div> | 10 | </div> |
11 | <slot></slot> | 11 | <slot></slot> |
12 | </div> | 12 | </div> |
13 | </template> | 13 | </template> |
14 | + | ||
14 | <script> | 15 | <script> |
15 | module.exports = { | 16 | module.exports = { |
16 | - props: ['data', 'type', 'val'], | ||
17 | - computed: {}, | 17 | + props: { |
18 | + data: { | ||
19 | + type: Array, | ||
20 | + default() { | ||
21 | + return []; | ||
22 | + } | ||
23 | + }, | ||
24 | + value: { | ||
25 | + type: Array, | ||
26 | + default() { | ||
27 | + return []; | ||
28 | + } | ||
29 | + }, | ||
30 | + type: { | ||
31 | + type: String | ||
32 | + } | ||
33 | + }, | ||
34 | + data() { | ||
35 | + return { | ||
36 | + currentData: [], | ||
37 | + currentValue: this.value, | ||
38 | + subType: this.type | ||
39 | + }; | ||
40 | + }, | ||
41 | + created() { | ||
42 | + this.renderData(); | ||
43 | + }, | ||
44 | + watch: { | ||
45 | + value(val) { | ||
46 | + this.currentValue = val; | ||
47 | + this.renderData(); | ||
48 | + } | ||
49 | + }, | ||
18 | methods: { | 50 | methods: { |
19 | select: function(val) { | 51 | select: function(val) { |
20 | - this.$dispatch('select', val); | 52 | + let itemIndex = this.currentValue.findIndex(item => item.id === val.id); |
53 | + | ||
54 | + if (itemIndex >= 0) { | ||
55 | + this.currentValue.splice(itemIndex, 1); | ||
56 | + } else { | ||
57 | + this.currentValue.push({ | ||
58 | + id: val.id, | ||
59 | + name: val.name | ||
60 | + }); | ||
61 | + } | ||
62 | + this.$emit('select', { | ||
63 | + value: this.currentValue, | ||
64 | + subType: this.subType | ||
65 | + }); | ||
66 | + }, | ||
67 | + renderData() { | ||
68 | + this.currentData = this.data.map(item => { | ||
69 | + return { | ||
70 | + id: item.id, | ||
71 | + name: item.name, | ||
72 | + checked: this.currentValue.some(val => val.id === item.id) | ||
73 | + }; | ||
74 | + }); | ||
21 | } | 75 | } |
22 | } | 76 | } |
23 | }; | 77 | }; |
1 | <template> | 1 | <template> |
2 | <ul class="list-box"> | 2 | <ul class="list-box"> |
3 | - <li v-for="item in items"><a class="no-intercept" href="#{{item.index}}">{{item.name}}</a></li> | 3 | + <li v-for="item in items" :key="item.name"><a class="no-intercept" href="#{{item.index}}">{{item.name}}</a></li> |
4 | </ul> | 4 | </ul> |
5 | </template> | 5 | </template> |
6 | <style> | 6 | <style> |
@@ -62,6 +62,8 @@ | @@ -62,6 +62,8 @@ | ||
62 | index: '0~9', | 62 | index: '0~9', |
63 | name: '#' | 63 | name: '#' |
64 | }); | 64 | }); |
65 | + } else { | ||
66 | + this.items = this.indexList; | ||
65 | } | 67 | } |
66 | } | 68 | } |
67 | }; | 69 | }; |
public/vue/product/new/demo.vue
0 → 100644
1 | +<template> | ||
2 | + <div> | ||
3 | + <filter-sub :value="valueData" :type="subType" :data="filterData" v-ref:filter-sub @select="selected"></filter-sub> | ||
4 | + <button @click="open('group_sort')"><h2>品类</h2></button> | ||
5 | + <button @click="open('brand')"><h2>品牌</h2></button> | ||
6 | + <button @click="open('color')"><h2>颜色</h2></button> | ||
7 | + <div>品类:<span v-for="item in values.group_sort" :key="item.id">{{item.name}} </span></div> | ||
8 | + <div>品牌:<span v-for="item in values.brand" :key="item.id">{{item.name}} </span></div> | ||
9 | + <div>颜色:<span v-for="item in values.color" :key="item.id">{{item.name}} </span></div> | ||
10 | + </div> | ||
11 | +</template> | ||
12 | + | ||
13 | +<script> | ||
14 | +const $ = require('jquery'); | ||
15 | +const filterSub = require('component/product/filter/filter-sub.vue'); | ||
16 | + | ||
17 | +module.exports = { | ||
18 | + data() { | ||
19 | + return { | ||
20 | + filterConfig: {}, | ||
21 | + subType: '', | ||
22 | + values: { | ||
23 | + group_sort: [], | ||
24 | + brand: [], | ||
25 | + color: [], | ||
26 | + } | ||
27 | + }; | ||
28 | + }, | ||
29 | + computed: { | ||
30 | + filterData() { | ||
31 | + return this.filterConfig ? this.filterConfig[this.subType] : {}; | ||
32 | + }, | ||
33 | + valueData() { | ||
34 | + return this.values && this.values[this.subType]; | ||
35 | + } | ||
36 | + }, | ||
37 | + created() { | ||
38 | + $.get('/product/new.json').then(config => { | ||
39 | + this.filterConfig = config.data.filter; | ||
40 | + }); | ||
41 | + }, | ||
42 | + methods: { | ||
43 | + open(subType) { | ||
44 | + this.subType = subType; | ||
45 | + this.$refs.filterSub.isVisible = true; | ||
46 | + }, | ||
47 | + selected(params) { | ||
48 | + this.values[params.subType] = params.value; | ||
49 | + console.log(this.values); | ||
50 | + } | ||
51 | + }, | ||
52 | + components: { | ||
53 | + filterSub | ||
54 | + } | ||
55 | +}; | ||
56 | +</script> | ||
57 | + | ||
58 | +<style> | ||
59 | +</style> |
@@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
4 | <i v-if="isiOS" class="icon icon-filter" slot="right" @touchstart="openFilter"></i> | 4 | <i v-if="isiOS" class="icon icon-filter" slot="right" @touchstart="openFilter"></i> |
5 | <i v-else class="icon icon-filter" slot="right" @click="openFilter"></i> | 5 | <i v-else class="icon icon-filter" slot="right" @click="openFilter"></i> |
6 | </cheader> | 6 | </cheader> |
7 | + <demo></demo> | ||
7 | <List :data="productList" :state="listState"></List> | 8 | <List :data="productList" :state="listState"></List> |
8 | <Filter :config="filterConfig" action="/product/list.json" v-ref:filter></Filter> | 9 | <Filter :config="filterConfig" action="/product/list.json" v-ref:filter></Filter> |
9 | </div> | 10 | </div> |
@@ -20,6 +21,7 @@ | @@ -20,6 +21,7 @@ | ||
20 | const cheader = require('component/header.vue'); | 21 | const cheader = require('component/header.vue'); |
21 | const list = require('component/product/list.vue'); | 22 | const list = require('component/product/list.vue'); |
22 | const filter = require('component/product/filter.vue'); | 23 | const filter = require('component/product/filter.vue'); |
24 | + const demo = require('./demo.vue'); | ||
23 | 25 | ||
24 | let locationQuery = qs(decodeURIComponent(location.search.replace(/^\?/, ''))); | 26 | let locationQuery = qs(decodeURIComponent(location.search.replace(/^\?/, ''))); |
25 | 27 | ||
@@ -70,7 +72,8 @@ | @@ -70,7 +72,8 @@ | ||
70 | components: { | 72 | components: { |
71 | cheader, | 73 | cheader, |
72 | list, | 74 | list, |
73 | - filter | 75 | + filter, |
76 | + demo | ||
74 | }, | 77 | }, |
75 | methods: { | 78 | methods: { |
76 | search: function() { | 79 | search: function() { |
-
Please register or login to post a comment