Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态(全局转态管理模式、同级组件之间的数据传递和通信)
获取Vux的状态以及获取的方式(getters)
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
name: "vuex",
},
getters: {
contactName: (state) => {
return state.name + "拼接";
},
},
});
// 创建一个 Counter 组件
const Counter = {
template: `<div>{{ this.$store.getters.contactName }}</div>`,
}
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
}
}
})
//对象的提交方式
methods: {
//点击事件
clickFun() {
this.$store.commit({
type: 'increment',
amount: 10
});
},
},
也可以用 dispatch 在actions里提交存储
export default new Vuex.Store({
state: {
age: 20,
},
mutations: {
increment(state, n) {
state.age += n;
},
},
actions: {
incrementAction({ commit }, val) {
commit("increment", val);
},
},
modules: {},
});
methods: {
clickFun1() {
this.$store.dispatch({
type: 'incrementAction',
amount: 10
});
},
},
获取Vux的最终形式
- 引入
import { mapState} from "vuex";
computed: {
...mapState({
count: (state) => state.count,
}),
},
也可以直接在事件里传参数 通过mapActions改变值
import { mapActions } from "vuex";
export default new Vuex.Store({
state: {
usernames: "",
},
mutations: {
username(state, n) {
state.usernames = n;
},
},
actions: {
incrementusername({ commit }, val) {
commit("username", val);
},
},
modules: {},
});
- 用的时候引入
add("你好")
...mapActions({
add: "incrementusername",
}),
Vux 持久化-解决刷新数据消失的问题
vuex可以进行全局的状态管理,但刷新后刷新后数据会消失,这是我们不愿意看到的。怎么解决呢,我们可以结合本地存储做到数据持久化,也可以通过插件-vuex-persistedstate
- 安装
npm install vuex-persistedstate --save
- 引入配置
在store下的index.js中
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({ // ... plugins: [createPersistedState()] })
默认存储到localStorage
想要存储到sessionStorage,配置如下
import createPersistedState from "vuex-persistedstate" const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage
})]
})
想使用 cookie同理 默认持久化所有state
Vuex模块化(Module)
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module) 。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
实践中,我们会经常用到 ES2015 的 参数解构 (opens new window)来简化代码(特别是我们需要调用 commit 很多次的时候):
- 在 store文件下创建需要的文件
const User = {
state: {
username: "100",
password: "200",
},
mutations: {
usernameF(state, val) {
state.username = val.username;
state.password = val.password;
},
},
actions: {
usernameFActions({ commit }, val) {
console.log(val);
commit("usernameF", val);
},
},
//这个必须要写 解决了文件混乱变量复杂的问题
namespaced: true,
};
export default User;
- 在store index 下进行引入
//引入的文件地址
import User from "./user/index";
modules: {
User,
},
- 在存放的时候与之前的方式不同
- 第一种用的是 this.$store的方式
methods:{
//点击触发的事件
loginFun() {
//this.value 是发送的值
this.$store.dispatch("User/usernameFActions", this.value);
},
}
- 第一种用的是 mapActions方式
//再次之前需要解构
methods:{
//some/nested/module store文件里引入模块化抛出路径
...mapActions('some/nested/module', [
'foo', // -> this.foo()
'bar' // -> this.bar()
]
),
//点击触发的事件
loginFun() {
//this.value 是发送的值
this.usernameFActions(this.value);
},
}
给插件开发者的注意事项
如果你开发的插件(Plugin)提供了模块并允许用户将其添加到 Vuex store,可能需要考虑模块的空间名称问题。对于这种情况,你可以通过插件的参数对象来允许用户指定空间名称
// 通过插件的参数对象得到空间名称
// 然后返回 Vuex 插件函数
export function createPlugin (options = {}) {
return function (store) {
// 把空间名字添加到插件模块的类型(type)中去
const namespace = options.namespace || ''
store.dispatch(namespace + 'pluginAction')
}
}