Vue2电商前台项目——完成Search搜索模块业务
Vue基础知识点击此处——Vue.js
文章目录
一、项目开发的步骤
1、书写静态页面
2、拆分组件
3、获取服务器的数据动态展示:写api => Vuex调用api把数据放store => 组件拿到仓库store的数据 => 动态渲染
4、完成相应的动态业务逻辑
这里拆分组件比较简单,把中间这部分拆分出来,其他地方直接在Search组件中保留
建议大家多熟悉熟悉Vuex,熟能生巧,做多了发现并不难,都是一个套路,点击此处——Vuex
二、各种请求数据并展示数据
流程:写api => Vuex调用api请求数据放store => 组件拿到仓库store的数据 => 动态渲染
1、写Search模块的接口
这是向真正的服务器发请求,所以用封装好的axios实例:requests。带参数,且参数params至少有个默认值(空对象{}
)否则会请求失败。
src/api/index.js
//本文件用于:API的统一管理
import requests from './request'; //axios请求后台ajax数据
import mockRequests from './mockRequest'; //axios请求后台mock数据
........
........
//4.Search模块的接口
// /api/list post 需要带参数,且参数params至少有个默认值(空对象{})否则会请求失败
export const reqSearchInfo = function (params) {
return requests({
url: '/list',
method: 'post',
data: params //请求体参数
})
}
2、写Vuex中的search仓库
注意调用接口时要传参,默认值要设置为空对象,不然请求会失败的
src/store/search/index.js
//本文件用于配置search模块的数据
import {
reqSearchInfo } from '@/api'
export const search = {
namespaced: true,
state: {
searchInfo: {
}
},
actions: {
async getSearchInfo(context, params = {
}) {
let result = await reqSearchInfo(params); //这里至少要传一个默认参数:空对象,否则请求不成功
if (result.code === 200) {
context.commit('GETSEARCHINFO', result.data);
}
}
},
mutations: {
GETSEARCHINFO(state, value) {
state.searchInfo = value;
}
},
getters: {
}
}
3、组件拿到search仓库的数据
(1)观察数据结构
观察数据,我们要拿到searchInfo
中的attrsList,goodsList,trademarkList
对应的关系是这样的:
(2)配置getters来简化数据
如果不使用getters而是使用mapState来接收的话,实际上是很麻烦的,每次都要写state.search.searchList.XXX,而且很容易出错
所以这里我们选择在仓库中配置getters:
//getters类似计算属性,可以简化仓库中的数据
getters: {
//当前形参是当前仓库的state
goodsList(state) {
//要等searchInfo的数据拿回来了再返回值,要不然可能就直接拿空对象了
return state.searchList.goodsList || []; //如果没网返回空数组
},
attrsList(state) {
return state.searchList.attrsList || [];
},
trademarkList(state) {
return state.searchList.trademarkList || [];
},
}
注意这里如果没网的话请求不到数据,searchInfo就是空对象,再点儿什么什么会是undefined,这时候我们要加个或的条件,默认空数组,这样没网时遍历空数组就不会出问题
从组件读取getters数据:
注意:如果开启了命名空间,就要写成:...mapGetters('search', ['goodsList', 'attrsList', 'trademarkList'])
4、渲染商品数据到页面
v-for遍历数组,然后把对应的数据填进去就行了
5、search模块根据不同的参数获取数据展示
后端对数据处理完后,返回筛选后的响应体,然后仓库中拿着筛选后的响应体给state => state再给getters处理一下子 => 组件再用mapGetters接收 => 再把数据更新到页面
(1)把派发actions的操作封装为函数
当用户点击搜索或三级联动的时候,需要根据关键字再发一次请求来获取相应的数据,而我们派发action
请求数据的操作是放在Search的mounted
挂载函数里面的,而我们在Search
页再点搜索或三级联动时,mounted不会再执行了.
所以我们应该把派发actions请求的操作封装成函数,在需要时候调用。
(2)设置参数默认值
观察api接口文档,发现向服务器发请求时可以带10个参数,我们将这些参数的默认值配置在Search组件的data中,以对象的形式存储,然后在派发actions请求时把这个对象传过去,就能够作为axios发送ajax请求的请求体参数,然后后台拿着这些传过来的参数进行一些筛选排序之类的操作。
(3)Object.assign合并对象
复习一个api:Object.assign(target, source)
,它有个功能是可以合并具有相同属性的对象,返回修改后的对象
(4)把三级联动或搜索的参数拿过来
用上面那个api,可以把我们点击三级联动或搜索时query和params参数拿过来(注意名字要一致),然后重名的属性相继覆盖。
这里要在mounted
之前(created
或beforeMount
都行),因为要在派发请求之前拿到带三级联动或搜索带的query和params参数的searchParams
,这样就可以将我们从三级联动或搜索获取到的参数覆盖掉初始带给服务器的参数。
后面两个对象依次覆盖前面重复的属性值,最后第一个对象原值改变,返回第一个对象,这样就能把相应的参数带给后端,然后后端再一过滤啥的,就能实现搜索功能了
(5)点击三级联动或搜索就再次请求数据
我们目前呢还是只发了一次请求,因为只在
mounted
里面调用了getData()
,但是我们必须实现点击
三级联动或搜索就调用getData()
(发送Ajax请求)
我们观察开发者工具,会发现其实跳转到路由组件后,组件身上的data
中会有$route
这个数据
每次用户点击三级联动或者搜索,都会触发push
路由跳转和传参(如果已经跳了就只传参),那么我们在进入Search组件
后,每次点击三级联动或者搜索都会带来$route
中参数的变化,也就是$route
的变化。
那么这样的话我们就可以去监视$route的变化,每次只要参数发生变化,就重新整理数据并派发请求,然后服务器根据传过去的参数做一些操作(筛选),然后把处理过的数据响应过来,就可以在页面展示了
6、渲染子组件数据到页面
子组件用到的是getters中的attrsList
和 trademarkList
这里和前面Floor是不同的,这里可以直接让子组件从仓库中拿数据,这是因为这个数据的结构是{ [], [], [] ...}
,而且我们已经通过getters把每个数组分出来了,且没有组件复用的情况,所以不用父传子(当然父传子也可以,但是没必要)
拿到数据之后v-for对应生成列表就行</