课程名称: CRMEB uniapp电商项目二次开发实战
课程章节: 5-2 商品列表页排序组件开发
课程讲师: CRMEB
课程内容:
1、新建排序组件sort.vue
<template> <view class="sort"> <view class="sort-container"> <view class="list"> <view v-for="(item, idx) in menuList" :key="idx" class="item" @click="onSwitchSort(idx)"> <text :class="{ 'font-color-red': item.sortValues[item.sortValueIndex] === 1 }">{{ item.text }}</text> <view v-if="hasIcon(item.sortValues[item.sortValueIndex])" class="icon icon--default" :class="[`icon--${item.sortValues[item.sortValueIndex]}`]"> </view> </view> </view> </view> </view> </template> <script> const SORT_VALUE = ['default', 'asc', 'desc'] export default { data() { return { menuList: [ { text: '新品上线', sortValueIndex: 0, sortValues: [1] }, { field: 'priceOrder', text: '价格', sortValueIndex: 0, sortValues: SORT_VALUE, union: false }, { field: 'salesOrder', text: '销量', sortValueIndex: 0, sortValues: SORT_VALUE, union: false }, { field: 'news', text: '新品', sortValueIndex: 0, sortValues: [0, 1], union: true } ] } }, computed: { hasIcon () { return function (sortValue) { return SORT_VALUE.includes(sortValue) } }, params () { let tempParams = {} for (let i = 0; i < this.menuList.length; i++) { const tempSortItem = this.menuList[i] if (tempSortItem.field !== undefined) { tempParams[tempSortItem.field] = tempSortItem.sortValues[tempSortItem.sortValueIndex] } } return tempParams } }, watch: { params (newVal) { this.$emit('sort', newVal) } }, methods: { onSwitchSort (idx) { const curSortItem = this.menuList[idx] for (let i = 0; i < this.menuList.length; i++) { const tempSortItem = this.menuList[i] if (i === idx) { tempSortItem.sortValueIndex = (tempSortItem.sortValueIndex + 1) % tempSortItem.sortValues.length } else { if ((false === (curSortItem.union || tempSortItem.union)) && (curSortItem.field !== undefined)) { tempSortItem.sortValueIndex = 0 } } } if (idx === 0) { uni.navigateBack() } } } } </script> <style lang="scss" scoped> .sort { position: fixed; left: 0; top: 86rpx; z-index: 9; width: 100%; height: 86rpx; &-container { color: #454545; font-size: 28rpx; height: 100%; box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); background-color: #fff; .list { display: flex; align-items: center; height: 100%; .item { display: flex; justify-content: center; align-items: center; flex: 1; height: 100%; .icon { display: inline-block; width: 7px; height: 9px; margin-left: 5px; background: url(~@/static/images/sort.png) no-repeat; background-position: 0 100px; &--default { background-position: 0 0; background-size: 100% auto; } &--asc { background-position: 0 -9px; background-size: 100% auto; } &--desc { background-position: 0 -18px; background-size: 100% auto; } } .font-color-red { color: #fc4141; font-weight: 700; } } } } } </style>
2、在商品列表中引入组件,注册并使用
<template> <view class="goods-list"> <view class="goods-list-container"> <Search @search="onSearch" @switch-mode="onSwitchShowMode"></Search> <Sort @sort="onSort" ref="sort"></Sort> <ProductList :list="goodsList" :showMode="showMode"></ProductList> </view> </view> </template> <script> import { productList as productListApi } from '@/api/goods' import Search from './components/Search' import Sort from './components/Sort' import ProductList from './components/ProductList' export default { components: { Search, Sort, ProductList }, data() { return { params: { // 一级分类id cid: 0, // 二级分类id sid: 0, // 搜索关键词 keyword: '', // 价格排序 priceOrder: '', // 按销量排序 salesOrder: '', // 是否新品 news: '', page: 1, limit: 20, }, goodsList: [], showMode: '', noMore: false } }, onLoad (options) { this.params.sid = options.sid this.$refs.sort.menuList[0].text = options.sname this.getProductList() }, onReachBottom () { this.getProductList() }, methods: { onSearch (keywords) { this.params.keyword = keywords this.params.page = 1 this.noMore = false this.getProductList() }, onSwitchShowMode (modeName) { this.showMode = modeName }, onSort (sortParams) { this.params = {...this.params, ...sortParams} this.params.page = 1 this.noMore = false this.getProductList() }, async getProductList () { if (this.noMore) { return false } const { status, data, msg } = await productListApi(this.params) if (status === this.API_STATUS_CODE.SUCCESS) { if (this.params.page > 1) { this.goodsList = [...this.goodsList, ...data] if (data.length === 0) { this.noMore = true } } else { this.goodsList = data } if (data.length) { this.params.page++ } } else { uni.showToast({ icon: 'none', title: msg, duration: 3000 }) } } } } </script> <style lang="scss" scoped> </style>
3、商品列表的展示形式替换
<template> <view class="search"> <view class="search-container"> <view class="search-input"> <text class="iconfont icon-sousuo"></text> <input v-model="keywods" placeholder="搜索商品名称" @confirm="onSearch"/> </view> <view class="show-mode" @click="onSwitchShowMode"> <text class="iconfont" :class="[`icon-${showMode[curShowModeIdx].val}`]"></text> </view> </view> </view> </template> <script> export default { data() { return { keywods: '', showMode: [ { val: 'pailie' }, { val: 'tupianpailie' } ], curShowModeIdx: 0 } }, created () { this.$emit('switch-mode', this.showMode[this.curShowModeIdx].val) }, methods: { onSearch (event) { this.$emit('search', event.detail.value) }, onSwitchShowMode () { this.curShowModeIdx = (this.curShowModeIdx + 1) % this.showMode.length this.$emit('switch-mode', this.showMode[this.curShowModeIdx].val) } } } </script> <style lang="scss" scoped> .search { position: fixed; left: 0; top: 0; z-index: 9; width: 100%; height: 86rpx; &-container { display: flex; justify-content: space-between; align-items: center; padding-left: 22rpx; height: 100%; background-color: #e93323; .search-input { display: flex; justify-content: space-between; align-items: center; width: 640rpx; height: 60rpx; background-color: #fff; border-radius: 50rpx; padding: 0 20rpx; box-sizing: border-box; .icon-sousuo { font-size: 34rpx; color: #555; } input { width: 548rpx; height: 100%; font-size: 26rpx; } } .show-mode { width: 62rpx; height: 86rpx; color: #fff; line-height: 86rpx; .iconfont { font-size: 40rpx; } } } } </style>
课程收获:
这节课学习到了精灵图的的建立与使用,首先使用background: 路径 no-repeat;引入图片,在使用 background-position对图片进行定位,在设置 background-size图片的大小,精灵图可以减少网络的请求,加快页面的访问速度,还有学习到了利用模运算实现代码元素的循环展示,首先是定义下需要循环的元素,再定义一个变量用于表示当前展示的形式,然后根据点击切换做加1操作,然后对模取余,就是实现了元素循环展示的计算,再有就是学习到了排他的事件绑定,还有学习了通过includes计算展示样式