官网文档
概念
-
Vuex
是适用于在Vue
项目开发时使用的状态管理工具 -
Vue
为被多个组件频繁使用的值提供了一个统一管理的工具Vuex
- 在
Vuex
的Vue
项目中,我们只需要把这些值定义在Vuex
中,即可在整个Vue
项目中使用
Vuex核心内容
在VueX
对象中,其实不止有state
,还有用来操作state
中数据的方法集,以及当我们需要对state
中的数据需要加工的方法集等等成员。
成员列表:
- state 存放状态
- mutations state成员操作
- actions 加工state成员给外界
- getters 异步操作
- modules 模块化状态管理
Vuex工作流程
vuex工作流程.png- 首先,
Vue
组件如果调用某个VueX
的方法过程中需要向后端请求时或者说出现异步操作时,需要dispatch
VueX
中actions
的方法,以保证数据的同步。 - 可以说,
action
的存在就是为了让mutations
中的方法能在异步操作中起作用。 - 如果没有异步操作,那么我们就可以直接在组件内提交状态中的
Mutations
中自己编写的方法来达成对state
成员的操作。 - 不建议在组件中直接对
state
中的成员进行操作,这是因为直接修改(例如:this.$store.state.name = 'hello'
)的话不能被VueDevtools
所监控到。 - 最后被修改后的
state
成员会被渲染到组件的原位置当中去
state
-
state仓库,存储数据的地方,它是响应式的,
-
在state事先声明的变量是响应式的
-
后续添加的属性,就不是响应式的,
-
解决办法:
-
和数组类似,
//vue.set(要修改的对象,属性,修改的值) // 添加或修改代码示例 Vue.set(staet.info,"address",'武汉') // 这个操作回将变量添加到 观察者中 // 删除代码示例 Vue.delete(state, 'name');
-
这样的操作,不仅操作l数据,还将关联响应式,直接添加删除,会没有响应式
-
-
mutations
-
mutations
是操作state数据的方法的集合,比如对该数据的修改、增加、删除等等。 -
使用方法
-
mutations
方法都有默认的形参:([state], [payload])
-
state:是当前
Vuex
对象中的state
- payload:是该方法在被调用时传递参数使用的
-
state:是当前
-
-
带参数的使用代码示例
- 普通字符传形式提交
// 单个值提交,(多个值传递,直接放在对象中即可) methods: { add(){ this.$store.commit('edit', 13); } }, // 这样在我们的mutation方法中就可以通过payload得到传过来的 13 mutations: { edit(state, payload){ console.log('payload', payload); // 13 state.name = '学习vuex'; } }
- 对象形式提交
this.$store.commit({ type: 'edit', user: 'lazy_tomato', age:18 }) mutations: { edit(state, payload){ console.log('payload', payload); // { // type: 'edit', // user: 'lazy_tomato', // age:18 // } state.name = payload.user; } }
Actions
-
actions
和mutations
的区别其实在于,我们一般使用mutations
做同步操作,异步操作我们都会写在actions
里面,因为在mutations
做异步操作,我们的调试工具和视图无法直接同步,会受到约束限制,但是我们actions
就没有这种约束/ - 简单说,就是为了将异步操作和非异步操作分离开,我们使用
actions
就是来进行异步操作的,让你的代码逻辑更加清晰. - 用法示例
// 调用使用 dispatch
this.$store.dispatch('incrementAsync');
mutations: {
addNum(state){
state.num++;
}
},
actions: {
addNum(context){
context.commit('addNum');
},
incrementAsync ({ commit }) {
setTimeout(() => {
commit('addNum')
}, 1000)
}
}
-
比较重要的几点有关于action
- 异步操作,应该放在action中运行。
- Action 提交的是 mutation,而不是直接变更状态。
- 使用this.store.dispatch,它可以直接返回一个promise对象,只需action中return即可。
Getters (类似于计算属性)
-
getters
可以对state
中的成员加工后传递给外界 -
使用方法
-
getter
中的方法有两个默认参数-
state:当前
vuex
对象中的状态对象 -
getters:当前
getters
对象,用于将getters
下的其他getter
拿来使用
-
state:当前
-
-
定义使用
getters: { nameInfo(state){ return `姓名:${state.name}`; }, fullname(state, getters){ // getters.nameInfo:表示将getters这个对象下面的nameInfo这个getter拿来使用 return `${getters.nameInfo},年龄:${state.age}`; } },
-
调用
<h1>{{ $store.getters.fullname }}</h1>
-
给Getter传参
-
定义一个getter 直接返回一个函数,即可。
// 定义 // say(status) { // return function a(X) { // return status.number + X // } // } // 转成箭头函数 say:status =>{ return (X)=> { return status.number + X } }
<!-- 使用 --> <h1>{{ $store.getters.say("后缀1")}}</h1>
-
modules
-
Vuex
允许我们将store
分割成模块(module)。每个模块拥有自己的state
、mutation
、action
、getter
、甚至是嵌套子模块——从上至下进行同样方式的分割 -
注册
module
const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: { demo: 'demo' }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }) export default store
-
页面获取
store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态 <h1>{{ $store.state.b.demo }}</h1>
-
我们可以把我们之前写的改写成模块
import Vue from 'vue' import Vuex from 'vuex' // 挂载vuex Vue.use(Vuex) const moduleA = { state: { // 存放的键值对就是所要管理的状态 name: `litian`, num: 0 }, getters: { nameInfo(state){ return `姓名:${state.name}`; }, fullname(state, getters){ // getters.nameInfo:表示将getters这个对象下面的nameInfo这个getter拿来使用 return `${getters.nameInfo},年龄:${state.age}`; } }, mutations: { // 没有传递参数的情况 edit(state, payload){ console.log('payload', payload); state.name = '学习vuex'; Vue.set(state, 'age', 18); // Vue.delete(state, 'name'); }, addNum(state){ state.num++; /* setTimeout(() => { state.num++; }, 1000); */ } }, actions: { addNum(context){ context.commit('addNum'); }, incrementAsync ({ commit }) { setTimeout(() => { commit('addNum') }, 1000) } } } const moduleB = { state: { demo: 'demo' } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } }); export default store
-
页面代码
<template> <div id="app"> <!-- <h1>{{ $store.state.name }}</h1> <h1>{{ $store.getters.fullname }}</h1> --> <h1>{{ $store.state.b.demo }}</h1> <h1>{{ $store.state.a.num }}</h1> <button @click="add">click</button> </div> </template> <script> export default { name: "App", data() { return { }; }, methods: { add(){ /* this.$store.commit('edit', { age: 18, sex: '女' }); */ /* this.$store.commit({ type: 'edit', user: { age: 18, sex: '女' } }) */ this.$store.commit('addNum'); // this.$store.dispatch('addNum'); // this.$store.dispatch('incrementAsync'); // console.log(this.$store.state.name); } }, }; </script>
网友评论