vuex是官方提供的一个插件,状态管理库,集中式管理项目中组件共用的数据。
切记:并不是所有项目都需要用到vuex,如果项目很小,完全不需要vuex;如果项目很大,组件很多,数据很多,数据维护很费劲,此时要用vuex。
state ----仓库存储数据的地方
mutations ----修改state的唯一手段
actions ----处理action,也可以书写自己的业务逻辑,也可以处理异步
getters ----理解为计算属性,用于简化仓库数据,让组件获取仓库的数据更加方便
1、单个仓库的配置
新建文件夹src/store/index.js,在里面创建仓库。
使用时,三连环,state存数据,通过调用actions里面的方法调用mutations来修改state里面的数据。
import Vue from 'vue';
import Vuex from 'vuex';
// 需要使用插件一次
Vue.use(Vuex);
// state:仓库存储数据的地方
const state = {count:1};
// mutations:修改state的唯一手段
const mutations = {
ADD(state){
state.count++
}
};
// action:处理action,也可以书写自己的业务逻辑,也可以处理异步
const actions = {
add({commit}){
commit("ADD");
}
};
// getters:理解为计算属性,用于简化仓库数据,让组件获取仓库的数据更加方便
const getters = {};
// 对外暴露Store类的一个实例
export default new Vuex.Store({
state,
mutations,
actions,
getters
});
2、引入、注册仓库
在main.js入口文件中引入、注册仓库
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
// 引入仓库
import store from '@/store';
new Vue({
render: h => h(App),
// 注册仓库:组件实例的身上会多一个$store属性
store
}).$mount('#app')
3、在组件中使用仓库中的数据
①组件中想用到仓库中的数据,可以使用辅助函数mapState: import {mapState} from 'vuex';
②映射为组件身上的数组:...mapState(['count'])
③在方法中派发action:this.$store.dispatch('add');
4、vuex实现模块式开发
如果项目过大,组件过多,接口也很多,数据也很多,可以让Vuex实现模块式开发。每一个模块使用一个小仓库,再统一管理小仓库。
home首页的小仓库src/store/home/index.js如下:
import { reqCategoryList,reqGetBannerList,reqFloorList } from "@/api";
// home模块的小仓库
const state = {
// state中数据默认初始值别瞎写,根据接口返回值类型初始化
// 三级菜单的数据
categoryList: [],
// 轮播图的数据
bannerList: [],
// floor的数据
floorList: []
};
const mutations = {
CATEGORYLIST(state,categoryList){
state.categoryList = categoryList;
},
GETBANNERLIST(state,bannerList){
state.bannerList = bannerList;
},
GETFLOORLIST(state,floorlist){
state.floorList = floorlist;
}
};
const actions = {
// 通过API里面的接口函数调用,向服务器发请求,获取服务器的数据
// 获取三级菜单的数据
async categoryList({commit}){
let result = await reqCategoryList();
// console.log(result);
if(result.code == 200){
commit('CATEGORYLIST', result.data);
}
},
// 获取首页轮播图的数据
async getBannerList({commit}){
// 发请求
let result = await reqGetBannerList();
// console.log(result);
if(result.code == 200){
commit('GETBANNERLIST', result.data);
}
},
// 获取floor数据
async getFloorList({commit}){
// 发请求
let result = await reqFloorList();
// console.log(result);
if(result.code == 200){
commit('GETFLOORLIST', result.data);
}
},
};
const getters = {};
export default {
state,
mutations,
actions,
getters
}
统一管理仓库src/store/index.js:
import Vue from 'vue';
import Vuex from 'vuex';
// 需要使用插件一次
Vue.use(Vuex);
// 引入小仓库
import home from './home';
import search from './search';
import detail from './detail';
import shopcart from './shopcart';
import user from './user';
import trade from './trade';
// 对外暴露store类的一个实例
export default new Vuex.Store({
// 实现Vuex仓库模块化开发存储数据
modules: {
home,
search,
detail,
shopcart,
user,
trade
}
})
在home组件中使用和操作仓库中的数据:
<template>
<div>
<!-- 三级联动全局组件,无需再次引入,可直接使用 -->
<TypeNav/>
<ListContainer/>
<Recommend/>
<Rank/>
<Like/>
<Floor v-for="(floor, index) in floorList" :key="floor.id" :list="floor"/>
<Brand/>
</div>
</template>
<script>
// 引入非全局其余组件
import ListContainer from '@/pages/Home/ListContainer';
import Recommend from '@/pages/Home/Recommend';
import Rank from '@/pages/Home/Rank';
import Like from '@/pages/Home/Like';
import Floor from '@/pages/Home/Floor';
import Brand from '@/pages/Home/Brand';
// ①引入mapState辅助工具
import {mapState} from 'vuex';
export default {
name: "Home",
components: {
ListContainer,
Recommend,
Rank,
Like,
Floor,
Brand
},
mounted() {
// ②派发获取floor数据的action,在action中会发送请求、将请求到的数据传到mutations中,在mutations中将收到的数据赋值给state中的floorList
this.$store.dispatch('getFloorList');
},
computed: {
// ③使用mapState映射数据
...mapState({
floorList: state => state.home.floorList
})
}
}
</script>
<style>
</style>
5、vuex数据业务梳理
以完成TypeNav三级联动展示数据业务为例。
步骤:
①准备好三级联动接口;
②初始化state里面的数据;
③在组件的mounted配置项中,通知vuex发请求:this.$store.dispatch("categoryList"); 此处的"categoryList"为action的函数名;
④在actions中配置一个action,名为"categoryList";发出请求reqCategoryList()拿到数据;
⑤写相关业务逻辑,并通过commit将数据交给mutations;
⑥mutations接收数据,修改state里面的初始化数据为接收到的数据;此时state里面即有从服务端拿到的真实数据;
⑦在组件中配置计算属性,将真实数据通过辅助函数 ...mapstate 绑定到组件身上;
// 函数的返回值作为计算属性categoryList的属性值,使组件拿到数据,然后再将拿到的数据进行展示
categoryList: (state) => {
// console.log(state);
return state.home.categoryList;
}
⑧在组件的结构里面可以对数据进行调用。