文章目录
Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex 是一个 Vue 的 状态(状态即为数据)管理工具,是Vue为我们提供的一个插件,它可以帮助我们管理共享状态,并附带了更多的概念和框架。
Vuex 核心概念——五大状态(属性)
vuex中一共有五个状态 State Getter Mutation Action Module 下面进行详细讲解
State ——存储状态
state: 提供唯一的公共数据源,所有共享的数据统一放到store的state进行储存,相似与data
在vuex中state中定义数据,可以在任何组件中进行调用
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
//数据,相当于data
state: {
name:"张三",
age:12,
count:0
},
})
调用:
方法一:
<p>{{ $store.state.name }}</p>
<p>{{ $store.state.age }}<p>
方法二:
通过this.$store.state.全局数据名称
this.$store.state.name
this.$store.state.age
方法三:
在vuex中按需导入辅助函数mapState
import { mapState } from "vuex";
在计算属性computed中通过...mapState([" 名称 "])
computed:{
...mapState(["name","age"])
}
这里 mapState
的作用就是帮我们把一个对象或数组里的值转化成计算属性的写法。将传入的数组或对象转成 computed 计算属性能够识别的代码。
...mapState
用了ES6的偷懒语法,箭头函数,在偷懒的时候要注意一个问题,this指针的指向问题,不要在vue中为了偷懒使用箭头函数,会导致很多很难察觉的错误,如果你在用到state的同时还需要借助当前vue实例的this,请务必使用常规写法.
Mutation ——修改状态
Mutation :更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。
在Mutation中,参数state参数是必须的,也可以自己传递一个参数。第二个参数为payload,作为使用中传递来的参数。
state: {
name: "张三",
age:12,
},
mutations: {
addAge(state,payload) {
if(payload){
state.age = +state.age+payload
}else{
state.age = state.age++
}
}
}
在组件中使用:
定义一个按钮进行操作
<button @click="add">哈哈又长一岁<button>
<button @click="addNum">我的年龄我做主,再加十岁<button>
方法一:
在methods中使用commit触发Mutation操作
method: {
add() {
this.$store.commit("addAge") //每次加一
}
addNum() {
this.$store.commit("addAgr",10) //每次加10
}
}
方法二:
在methods中用辅助函数mapMutations进行操作,
import { mapMutations } from "vuex"
methods: {
...mapMutations(["add"}),
add(){
this.addAge()
},
addNum(){
this.addAge(10)
}
}
Action ——进行异步操作
Action和Mutation相似,一般不用Mutation 异步操作,若要进行异步操作,使用Action
原因:
为了方便devtools打个快照存下来,方便管理维护。所以说这个只是规范,而不是逻辑的不允许,只是为了让这个工具能够追踪数据变化而已
state: {
name: "张三",
age:12,
},
mutations: {
addAge(state,payload) {
if(payload){
state.age = +state.age+payload
}else{
state.age = state.age++
}
}
}
actions: {
// 第一个参数context为上下文
// 第二个参数payload 为接收的参数
asyncAdd(context,payload) {
// 异步
setTimeout(() => {
context.commit("addAge")
},1000);
}
}
在组件中使用:
方法一:
直接使用 dispatch触发Action函数
this.$store.dispatch("asynAdd")
方法二:
在methods中使用辅助函数mapActions
methods: {
...mapActions(["asyncAdd"]),
add() {
this.asyncAdd();
}
}
Getter ——计算属性
getter类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据
state: {
name: "张三",
age:12,
},
getters: {
// 第一个参数 state
// 第二个参数 getters 其他计算属性
getNewName(state,getter){
return state.name+'法外狂徒'
}
}
在组件中使用
方法一:
直接使用 dispatch触发Action函数
this.$store.getters("getNewName")
方法二:
在methods中使用辅助函数mapActions
computed: {
...mapGetters(["getNewName"]),
getName() {
console.log(getNewName) // 张三法外狂徒
}
}
Modules ——模块化
当遇见大型项目时,数据量大,store就会显得很臃肿
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
modules: {
city: {
namespaced:true, //开启命名空间
state: {
name: '合肥',
num: 10
},
mutations: {
changeCity(state,payload){
if(payload){
state.name = payload
}else{
state.name = '上海'
}
}
},
getters: {
getNewNum(state,getter){
return state.num + 10
}
},
actions: {
changeOtherCity(context,payload){
setTimeout(()=>{
context.commit('changeCity','武汉')
},1000)
}
}
},
user: {
namespaced:true
state: {
name:'张二蛋'
}
}
}
默认情况下,模块内部的 action 和 mutation 仍然是注册在全局命名空间的——这样使得多个模块能够对同一个 action 或 mutation 作出响应。
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
在组件中使用模块内的状态
<p> 获取模块中state </p>
<p> {{ $store.state.city.name }} </p>
<p> {{ name }} </p>
<hr>
<p> 模块中mutations使用 </p>
<button @click="btn"> 改变城市</button>
<button @click="changeCity('广州')"> 变成广州</button>
<hr>
<p> 获取模块中getters </p>
<p> {{ $store.getters['city/getNewNum'] }}</p>
<p>{{ getNewNum }} </p>
<hr>
<p> 模块中actions使用 </p>
<button @click="btn1"> 改变城市</button>
<button @click="changeOtherCity('北京')"> 变成北京</button>
import { mapState,mapMutations,mapGetters,mapActions } from 'vuex'
computed:{
// 辅助函数获取模块中的state
...mapState('city',['name'])
// 辅助函数获取模块中的getter
...mapGetters('city',['getNewNum'])
},
methods:{
// 辅助函数修改模块中的状态mutation
...mapMutations('city',['changeCity'])
// 原生方法调用模块中的mutation
btn(){
this.$store.commit('city/changeCity')
}
// 辅助函数异步修改模块中状态actions
...mapActions('city',['changeOtherCity']
btn1(){
this.$store.dispath('city/changeOtherCity')
}
}