写在前面:
我是「沸羊羊_」,昵称来自于姓名的缩写 fyy ,之前呕心沥血经营的博客因手残意外注销,现经营此账号。
本人是个小菜,正向着全栈工程师的方向努力着,文章可能并不高产,也很基础,但每写一篇都在用心总结,请大佬勿喷。
如果您对编程有兴趣,请关注我的动态,一起学习研究。
感谢每位读者!
相信很多人都存在这样的情况, 在项目中vuex 会用,但让你回答 vuex 是什么?只能答出个大概,模模糊糊的概念。(不是我,真不是!)这篇文章将具体讲解什么是 vuex 以及如何以正确姿势打开 vuex?
Vuex是Vue.js应用程序的状态管理模式+库。 它充当应用程序中所有组件的集中存储,其规则确保状态只能以可预测的方式进行更改。 它还与Vue的官方devtools扩展集成,以提供高级功能,例如零配置时间旅行调试和状态快照导出/导入。
看完官网的概念是不是似懂非懂?我们通过一个小例子先来了解 vue.js 程序 页面结构。
new Vue({
// state
data () {
return {
count: 0
}
},
// view
template: `
{{ count }}
`,
// actions
methods: {
increment () {
this.count++
}
}
})
vue.js 由三部分组成: view、actions、state , 而 vuex 是Vue.js应用程序的状态管理模式+库。状态管理模式就是对 vue.js 的 state 进行管理的工具。而库是 vuex 工具给我们提供了一块区域存放 这些状态。更通俗的解释可以讲解为,vue 就是一个生产车间,而 vuex 可以当做带有仓库管理员的仓库,车间生产出来放到仓库存储,并由管理员负责管理仓库。
大概了解了 vuex 是做什么的了?有些同学可能提问了,vue.js 程序的页面中不是可以存放 state 吗?干嘛需要 vuex 来管理 state ?
问的好!学习一个新东西就是要从 what , how ,when ,why 等几个方面去引发思考。上面的小例子,展示的是单个页面,如果我的程序只是单页面这种小型程序,各个组件中不需要依赖同一状态,duck不必使用 vuex 来管理我们的 state 。但如果当你打算开发大型单页应用(SPA),会出现多个视图组件依赖同一个状态,来自不同视图的行为需要变更同一个状态。你就应该考虑使用Vuex了,它能把组件的共享状态抽取出来,当做一个全局单例模式进行管理。这样不管你在何处改变状态,都会通知使用该状态的组件做出相应修改。
下面,我们来说明 vuex 如何使用?
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state:{},
mutations:{},
getters:{},
actions:{},
modules:{}
})
Vuex 核心概念主要有以下几部分:
state
vuex 使用单个状态树,也就是一个应用程序中只需要一个 vuex 的实例即可管理你的所有状态。使用时,store.js 中的 state 对象中存放的都是你应用程序中的全局变量。使用起来也是非常容易,假设我们现在把组件中的状态抽离出来。
vuex(state) == vue(data)
state: {
token: "", //用户token
lists:[],
message:"给各个组件的消息!"
}
当各个组件想要使用这些状态时,如何调用呢?
//组件A
import { mapState } from "vuex"; // 引入vuex用于将全局变量映射为页面变量
computed:{
...mapState([ //解构到计算属性中
'message' //store.js 中的state
])
},
mutations
官网解释:实际更改Vuex存储中状态的唯一方法是提交一个突变。 Vuex突变与事件非常相似:每个突变都有一个字符串类型和一个处理程序。 处理函数是我们执行实际状态修改的地方,它将接收状态作为第一个参数。
mutations 也就是用来更改 store 的 state 的,相当于: vuex(mutations) == vue(methods),看看是如何使用的?
试想,我们需要在某一个组件中给 state 中的 list 数组添加数据。组件中是如何实现的呢?
//组件A
this.$store.commit("addList", this.data); // 存储 data 到 store 中
store 中如何接收组件A传递的数据呢?正如官网所说的,每个突变的第一个参数都是 state ,第二个参数为 组件A传递的数据。
// store.js 中负责接收组件A 的数据,并push 到 state 中的 list数组
mutations:{
addList(state, listData) {
state.lists.push(listData);
},
}
getters
试想某个组件中需要获取通过一定条件过滤后的 list ,这时候,我们可以使用 getters 来获取。 vuex(getters) 与 vue(computed) 相似, getters 也是将结果存入缓存,当数据变化后,再次调用。每一个 getters 都将 state 做为其第一个参数。
// store.js
getters: {
getList: state => {
return state.lists.filter(list => list.length > 5)
}
}
在组件中如何获取呢?
//组件A
import { mapGetters } from "vuex"; // 引入vuex用于将全局变量映射为页面变量
computed: {
...mapGetters([
'getList'
])
}
actions
actions 与 mutations 很相似,但不同之处在于:
试想我们需要某个组件在一段时间后执行某个操作。这时候,actions 支持异步,只能使用 actions
//store.js
//2s后向lists 数组添加数据
actions: {
add({ commit, state }, listData) {
setTimeout(function () {
//调用 mutations 的 addList 方法
commit("addList", listData);
}, 2000);
}
},
在组件中如何触发此actonis?
//组件A
methods: {
add(){
//使用 dispatch 触发 actions
this.$store.dispatch('add');
},
}
modules
当代码量不断增多,这个容器的状态和Mutations,actions,getters都太多了时,我们可以把它们按自己的需求进行分类,分成几个module,每个module和上面一样由state,mutations,actions,getters组成:
//store.js
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})