最近在项目中遇到了 vuex,大概整理了一下。项目的登录页面和登出页面调用了写在 vuex 里面的登录登出方法,vuex 里面判断了权限相关。因为是不同页面共享状态,所以用 vuex 比较方便。 如果是同页面,那还是组件传值更好用。
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。采用集中式管理组件的状态。
下面通过简单的例子看看使用方法,先新建一个 vue 项目,怎么新建 vue 项目这里就不讲了,不会的可以看我之前的文章 使用 vue-lic3 创建 vue 项目
建好项目后用命令 npm install vuex --save
安装 vuex,安装完后在 src 目录下新建 store 文件夹,里面新建 index.js 文件。(我现在用vue-cli4 创建的项目,自带 store 文件夹)
index.js 里面写入
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 创建一个 store
export default new Vuex.Store({
})
接下来在 main.js 文件里引入 store
import store from './store'
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
现在就可以用 vuex 了。
我们在刚创建的 store 里面写入 state
。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 创建一个 store
export default new Vuex.Store({
state: {
text: 'hello world'
}
})
新建一个页面,使用 this.$store.state.text 渲染 vuex 里面的数据。
<template>
<div>
<h2>{{ this.$store.state.text }}h2>
div>
template>
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像 computed 计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。在 store 写入 getters
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
text: 'hello world'
},
getters: {
getInFo: state => {
return state.text
}
}
})
页面代码
<h2>{{ this.$store.getters.getInFo }}h2>
数据也能正常渲染。
现在我们尝试修改数据,在页面里添加按钮。
<template>
<div>
<h2>{{ this.$store.getters.getInFo }}h2>
<button @click="handleChange">点击修改button>
div>
template>
<script>
export default {
methods: {
handleChange() {
this.$store.state.text = '哈哈哈哈哈哈哈'
}
}
};
script>
现在点击按钮可以成功修改文字。 但 vuex 不建议我们直接修改,而是通过提交 mutation 的方式去修改。在 store 中添加 mutation
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
text: 'hello world'
},
getters: {
getInFo: state => {
return state.text
}
},
mutations: {
handleChange (state) {
state.text = "通过提交 mutation 的方式修改"
}
}
})
然后在页面中修改方法。
handleChange() {
this.$store.commit('handleChange')
// this.$store.state.text = '哈哈哈哈哈哈哈'
}
Action 类似于 mutation,不同在于:
注册一个 Action
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
text: 'hello world'
},
getters: {
getInFo: state => {
return state.text
}
},
mutations: {
handleChange (state) {
state.text = "修改成功"
}
},
actions: {
handleChange (context) {
context.commit('handleChange')
}
}
})
在页面中用 this.$store.dispatch(‘handleChange’) 触发,dispatch 还可以传入第二个值做参数。
handleChange() {
this.$store.dispatch('handleChange')
// this.$store.commit('handleChange')
// this.$store.state.text = '哈哈哈哈哈哈哈'
}
乍一看多此一举,其实区别在 Action 可以异步,而 mutation 必须是同步函数。
一般情况下项目中有很多模块,这个时候 store 对象就显得非常臃肿,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
export default = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
更多请查看 参考文档