文章目录
一、Search模块
模块开发的几个步骤
- 静态页面+静态组件拆分
- 发请求(API)
- 数据保存到vuex中(配置好vuex中的actions、mutations、state)
- 组件获取vuex动态数据,渲染页面
1、Search模块的api
注意传递的参数至少应该是一个空对象,否则请求会出错。
// src/api/index.js 本文件对于API接口进行统一管理
import requests from './request'
import mockRequests from './mockRequest'
...
// 搜索模块数据,地址:/api/list 请求方式:post, 参数:需要带参数
// 当前这个接口,给服务器传递参数params,params至少应该是一个空对象,否则请求会出错
// 即: reqSearchInfo()----reqSearchInfo({})------不会出错
export const reqSearchInfo = (params) => {
return requests({
url: '/list', method: 'post', data: params })
}
在main.js中测试该api:
import {
reqSearchInfo } from './api'
reqSearchInfo({
})
得到的返回信息为:
2、Vuex保存数据
获取的是Search模块的数据,所以应该保存在search小仓库中:
// src/store/search/index.js
import {
reqSearchInfo } from '@/api'
export default {
namespaced: true,
state: {
searchList: {
} // 仓库初始状态
},
actions: {
async getSearchInfo (context, param = {
}) {
const result = await reqSearchInfo(param)
if (result.code === 200) {
console.log(result.data);
context.commit('GETSEARCHINFO', result.data)
}
}
},
mutations: {
GETSEARCHINFO (state, searchList) {
state.searchList = searchList
}
},
getters: {
...}
3、组件获取vuex数据并渲染
(1)、分析请求数据的数据结构
对应在页面上:
如果Search组件通过mapState读取这些数据(麻烦且易出错):
...mapState('search', {
goodsList: state => state.search.searchList.goodsList,
attrsList: state => state.search.searchList.attrsList,
trademarkList: state => state.search.searchList.trademarkList
})
(2)、getters简化数据、渲染页面
然后将数据渲染到页面即可,没什么重要的点。
4、Search模块根据不同的参数获取数据
(1)、 派发actions的操作封装为函数
目前派发actions的操作放在mounted里,组件挂载完毕会执行一次,但也只能发送一次。当搜索的参数发生变化时,应该再次发送请求,所以应该将请求封装成一个函数。
Search/index.vue
(2)、设置带给服务器的参数
之前写Search模块的api时,为了测试,参数传的是空对象。此处要配置参数具体的值。
观察api接口文档,发现向服务器发请求时可以带10个参数。我们将这些参数的默认值配置在Search组件的data中,以对象的形式存储,然后在派发actions请求时把这个对象传过去,就能够作为axios发送ajax请求的请求体参数。(这段话的原文链接:https://blog.csdn.net/weixin_42044763/article/details/126817322)
(3)、Object.assign整理参数值(该方法在JS高级的浅拷贝中提到过)
从首页的三级联动跳转到Search页面时,路由携带了query参数(categoryId与categoryName)。
Header组件搜索关键词跳转到Search页面时,路由携带了params参数(keyword)。
Search组件在挂载完时(mounted)就要发送一次请求获取页面数据以渲染页面。在发送请求之前,应该将携带的参数带给服务器。
// 封装参数,其实在mounted里也可以,这里是为了回顾一下生命周期函数
beforeMount () {
// 复杂
this.searchParams.category1Id = this.$route.query.category1Id
this.searchParams.category2Id = this.$route.query.category2Id
this.searchParams.category3Id = this.$route.query.category3Id
this.searchParams.categoryName = this.$route.query.categoryName
},
mounted () {
// 在这里整理参数也可以,只要在发送请求之前整理好即可
this.getData()
},
这种整理参数的方式也可以,但比较复杂,不是最优。采用Object.assign
优化一下。
Object.assign(target, source)
:可以合并具有相同属性的对象,返回修改后的对象。
beforeMount () {
Object.assign(this.searchParams, this.$route.query, this.$route.params)
},
mounted () {
// 在这里整理参数也可以,只要在发送请求之前整理好即可
this.getData()
}
至此实现了:从其他页面跳转到Search页面时,Search组件会根据已有的参数值向服务器请求对应的数据。渲染到页面上。但是当输入关键字或进行其他操作时,应该根据参数值再次发起请求,获取数据。
(4)、监听路由以实现根据不同参数 多次发送请求(有意思)
当路由发生变化时,说明发生了路由跳转,
5、SearchSelector读取动态数据
数据在进入Search页面时都请求到了,并且在Vuex中也用过getter简化了,所以这里直接从Vuex中取数据即可。不用父子组件传值。
SearchSelector.vue
这里用slice是因为返回的一些数据是测试数据,不好看,就不展示了。
二、面包屑
1、展示面包屑(关键词+分类名)
面包屑的值包括好几类,先看这两类:三级联动里的分类名,搜索输入框里的关键字。
可通过查看SearchParams
里是否包含分类名或者关键字来判断是否显示面包屑。
为什么SearchParams
里会包含这两个信息呢?在Search组件挂载完成(mounted)或者再次发送请求信息时,用户搜索的参数已整合到SearchParams
里了。
<!--Search.vue-->
<ul class="fl sui-tag">
<!-- 分类面包屑 -->
<li class="with-x" v-if="searchParams.categoryName">
{
{ searchParams.categoryName }}<i @click="deleteCategory">×</i