继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

【备战春招】第16天 商品列表页排序与列表的开发

imooc66
关注TA
已关注
手记 54
粉丝 2
获赞 23

课程章节: 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计算展示样式

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP