一 介绍
- Vue中的组件中数据传输主要是通过父子通信来传输数据.,但当项目达到了中大型的规模,组件中的通信逻辑将变得十分复杂,这个时候我们可以通过Vuex来解决,全局存放处理数据
- Vuex准确的官方定义是一种状态管理模式,集中式存储管理应用的所有组件状态,既是解决不同视图的状态依赖问题,统一进行管理调度
二 demo结构
- Vuex也可以模块化开发使用
- 声明建立一个store仓库,作为总入口
//index.js
//导入vuex ,声明一个store仓库用来做状态管理
import Vue from 'vue'
import Vuex from 'vuex';
import state from './state'
import mutations from './mutations'
import * as getters from './getters'
import * as actions from './actions'
Vue.use(Vuex)
export default new Vuex.Store({
state,
getters,
mutations,
actions,
})
三 使用
state
- 用于定义数据
- Vue 每一个应用只使用一个 state 单例,用一个状态书管理应用下的所有组件状态,在state中定义应用的数据,相当于data的初始化数据,不同的是state是对象类型
//state.js
const state = {
items: []
}
export default state
getter
- 用于返回值
- 类似于computed,getter的返回值也会根据它的依赖被缓存起来,只有它的依赖值发生改变时,才会开始改变。
- 功能上也相似,也被称为Vuex的修饰器,可以直接对state中数据进行一些操作和加工。不过一般用来返回state里面的值,不直接去暴露state中的值
- 接收的第一个参数为state,第二个为其他的getters
//getter.js
export const items = function(state){
return state.items;
}
mutation
- 修改值
- 更改Vuex中的数据唯一方法是提交mutation,使用中一般使用函数对数据进行修改,使用的函数的参数提出传入state,不过需要注意的是 mutation 中的函数为同步函数,不能使用异步函数。
- demo中 pushProduct() 函数实现添加商品到购物车,addNum() 实现 购物车中商品数量的增加
const mutations = {
pushProduct(state, product) {
state.items.push({
id: product.id,
title: product.title,
quantity: 1
})
},
addNum(state, product) {
const cartItem = state.items.find(item => item.id === product.id);
cartItem.quantity++;
}
}
export default mutations
Action
- Action 与mutation 很类似,Action提交的是mutation 而不是直接变更状态数据,Action 还可以包含异步操作。通常在Action中会使用上一级函数,来触发mutation中函数
- demo 中直接只暴露出一个方法,添加到购物车,再根据该商品是否已存在购物车中来判断执行 mutations 中的函数
export const addProduct = function({commit,state},product){
const cartItem = state.items.find(item => item.id === product.id);
if(!cartItem){
commit('pushProduct',{id:product.id,title:product.title});
}else{
commit('addNum',cartItem);
}
}
四 demo实现
- App.vue
<template>
<div>
<ul>
<li v-for="item in listData" :key="item.id">
<h3>{{ item.title }}</h3>
<button @click='addProduct(item)'>添加到购物车</button>
</li>
</ul>
<hr>
<h1>购物车</h1>
<ul>
<li v-for="item in items" :key="item.id">
<h1>{{item}}</h1>
</li>
</ul>
</div>
</template>
<script>
import { mapGetters,mapActions } from "vuex";
export default {
computed: {
...mapGetters(["items"]),
},
methods:{
...mapActions([
'addProduct'
])
},
data() {
return {
listData: [
{
id: 1,
title: "零食",
},
{
id: 2,
title: "水果",
},
{
id: 3,
title: "饮料",
},
{
id: 4,
title: "生鲜",
},
],
};
},
};
</script>
- 功能实现:
五 map辅助函数
- 以actions 或 mutations 为例,如果不使用 map 函数,actions 或 mutations 中存放的函数多了之后,当在app.vue 的主界面的引入会比较麻烦,会很臃肿
computed:{
userInfo(){
return this.$store.state.userInfo
},
token(){
return this.$store.state.token
},
friends(){
return this.$store.state.friends
},
likes(){
return this.$store.state.likes
},
...
}
而这里我们引入map 辅助函数即可,该方法还可以自动将需要的state值映射为实例的计算属性,声明的方法名默认为传入的方法名
import { mapActions } from "vuex";
computed: mapActions(['likes','friends','token','userInfo'])
但如果我们想自定义声明的方法名,而不是和传入的方法名一样,则可以使用三元运算符,实现自动匹配
import { mapActions } from "vuex";
computed: ...mapActions(['mylikes','myfriends','mytoken','myuserInfo'])
参考链接: vuex