<template>
<div class="list-container">
<!-- 排序区域 -->
<div class='sub-sort'>
<div class="sort">
<a
:class="{ active: sortField === null }"
@click="changeSort(null)"
href="javascript:;">默认排序</a>
<a
:class="{ active: sortField === 'publishTime' }"
@click="changeSort('publishTime')"
href="javascript:;">最新商品</a>
<a
:class="{ active: sortField === 'orderNum' }"
@click="changeSort('orderNum')"
href="javascript:;">最高人气</a>
<a
:class="{ active: sortField === 'evaluateNum' }"
@click="changeSort('evaluateNum')"
href="javascript:;">评论最多</a>
<a
:class="{ active: sortField === 'price' }"
@click="changeSort('price')"
href="javascript:;">价格
<i class="arrow up" :class="{active:sortParams.sortField==='price'&&sortParams.sortMethod=='asc'}" />
<i class="arrow down" :class="{active:sortParams.sortField==='price'&&sortParams.sortMethod=='desc'}" />
</a>
</div>
</div>
</div>
</template>
<script>
export default {
setup () {
const sortParams = reactive({
inventory: false,
onlyDiscount: false,
sortField: null,
sortMethod: 'desc'
})
// publishTime(最新), orderNum(人气), price(价格), evaluateNum(评论)
function changeSort (sortField) {
sortParams.sortField = sortField
// 对价格特殊处理
if (sortField === 'price') {
// 不是第一次点击:当前排序取反
sortParams.sortMethod = sortParams.sortMethod === 'desc' ? 'asc' : 'desc'
} else {
// 如果排序未改变停止逻辑
sortParams.sortMethod = 'desc'
}
console.log(sortParams.sortField, sortParams.sortMethod)
}
watch(sortParams, () => {
// 通知父组件重发请求
emit('sort-change', sortParams)
})
return { changeSort, sortParams }
}
}
</script>
1.定义获取数据的API
src/api/category.js
/**
* @description: 获取筛选商品
* @param {*} params
* @return {*}
*/
export const findSubCategoryGoods = (params) => {
return request('/category/goods', 'post', params)
}
2.编写获取数据逻辑
sub.vue
<script>
import { findSubCategoryGoods } from '@/api/category'
import { useRoute } from 'vue-router'
import { onMounted, ref} from 'vue'
export default {
setup () {
// 省略其他...
// 获取list
const goodList = ref([])
// 请求参数
const reqParams = {
page: 1,
pageSize: 20,
categoryId: route.params.id,
sortField: null, // 排序类别
attrs: [], // 商品属性
brandId: null // 品牌名称
}
const loadData = () => {
findSubCategoryGoods(reqParams).then(res => {
goodList.value = res.result.items
})
}
loadData()
return { subCategoryData, goodList }
}
}
</script>
3.渲染模板
引入goods-item组件
<script>
import GoodsItem from '@/views/Category/components/goods-item'
</script>
使用
<!-- 商品列表 -->
<div class="sort-list-container">
<GoodsItem v-for="good in goodList" :key="good.id" :goods="good"/>
</div>
样式
<style>
.sort-list-container {
display: flex;
flex-wrap: wrap;
}
</style>
4.从组件sub-filter抛出事件
const getFilter = () => {
// 收集目前的参数
const params = {
brandId: null,
// attrs: [
// {groupName: '款式', propertyName: '富士山款'},
// {groupName: '颜色', propertyName: '经典夜空黑'},
// ......
// ]
attrs: []
}
// 更新brandId
// 1.找出selected为true的那一项
const brand = props.subCate.brands.find(it => it.selected)
// 2.找到就用它的id,否则就是null
params.brandId = brand ? brand.id : null
// 更新attrs
params.attrs = props.subCate.saleProperties.forEach(item => {
const groupName = item.name
const propertyName = item.properties.find(it => it.selected).name
if (propertyName !== '全部') {
params.attrs.push({ groupName, propertyName })
}
})
return params
}
// 1.更新品牌数据
const selectBrand = (brand) => {
console.log(brand)
props.subCate.brands.forEach(it => {
it.selected = false
})
brand.selected = true
// 2.收集目前的参数,通知父组件重做查询
// 字传父:emit
emit('filter-change', getFilter())
}
const selectAttr = (prop, sale) => {
// 1.更新属性数据
console.log(prop, sale)
sale.properties.forEach(it => {
it.selected = false
})
prop.selected = true
// 2.收集目前的参数,通知父组件重做查询
emit('filter-change', getFilter())
}
5.监听事件
sub.vue
<SubFilter :cate="subCategoryData" @filter-change="filterChange" />
const loadData = () => {
findSubCategoryGoods(reqParams).then(res => {
goodList.value = res.result.items
})
}
loadData()
const filterChange = (sortParams) => {
console.log('查询条件', sortParams)
reqParams = { ...reqParams, ...sortParams }
reqParams.page = 1
goodList.value = []
isFinished.value = false
loadData()
}
6.从组件sub-sort抛出事件
setup (props, { emit }) {
const sortParams = reactive({
inventory: false, // 仅显示有货商品
onlyDiscount: false, // 仅显示特惠商品
sortField: null, // 排序字段 publishTime(最新), orderNum(人气), price(价格), evaluateNum(评论)
sortMethod: 'desc'// 顺序:asc升序 desc降序
})
const shangeSort = type => {
sortParams.sortField = type
if (type === 'price') {
sortParams.sortMethod = (sortParams.sortMethod === 'asc') ? 'desc' : 'asc'
} else { // 不是价格
sortParams.sortMethod = 'desc'
}
}
watch(sortParams, () => {
// 通知父组件重发请求
emit('sort-change', sortParams)
})
return { sortParams, shangeSort }
}
7.监听事件
<SubSort :cate="subCategoryData" @sort-change="sortChange"/>
const hSortChange = (sortParam) => {
console.log('父组件收到了排序条件', sortParam)
// 更新条件
// reqParams.inventory = sortParam.params.inventory
// reqParams.onlyDiscount = sortParam.params.onlyDiscount
reqParams = { ...reqParams, ...sortParam }
// 重置页码,清空数据
reqParams.page = 1
goodList.value = []
isFinished.value = false
// 重发请求
loadData()
}