10 KiB
Executable File
vuex
介绍
专为 Vue.js 应用程序开发的状态管理模式, 采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.
- 修改state状态必须通过
mutations
mutations
只能执行同步代码,类似 ajax、定时器之类的代码不能在mutations中执行- 执行异步代码,要通过
actions
,然后将数据提交给mutations
才可以完成 - state 的状态即共享数据可以在组件中引用
- 组件中可以调用 action / mutations
使用场景
不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。如果您的应用够简单,您最好不要使用 Vuex
下载 安装
npm install vuex --save
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(vuex)
const store = new Vuex.Store({})
new Vue({
el: '#app',
store
})
==Vuex有五个最重要的构造器: state, mutations, actions, getters, modules==
state
state是放置所有公共状态的属性,如果你有一个公共状态数据 , 你只需要定义在 state对象中
几种使用方法:
原始调用
组件中可以使用 this.$store 获取到vuex中的store对象实例
<div> state的数据:{{ $store.state.count }}</div>
结合计算属性
将state属性定义在计算属性中
computed: {
count () {
return this.$store.state.count
}
}
辅助函数 mapState
方便获取多个状态, 像前面在 computed 里多次定义太啰嗦
// 第一步:导入mapState
import { mapState } from 'vuex'
// 第二步:采用数组形式引入state属性
// 第三步:mapState函数返回的是对象, 利用展开运算符合并到计算属性里
computed: {
...mapState([
'count',
'count2',
//...
])
}
// 如果计算属性的名称和state的子节点名称不同
computed: {
...mapState({coutAlias: state => state.cout}),
}
// 使用
<div> state的数据:{{ count }}</div>
getters
除了state之外,有时我们还需要从state中派生出一些状态,这些状态是依赖state的,此时会用到 getters 可以认为是 store 的计算属性
例如,state中定义了list,为1-10的数组,组件中,需要显示所有大于5的数据
state: {
list: [1,2,3,4,5,6,7,8,9,10]
},
getters: {
// getters函数的第一个参数是 state
// 必须要有返回值
filterList: state => state.list.filter(item => item > 5)
}
===通过属性访问时会进行缓存===
getter 可以返回一个函数, 实现向 getter 传参
state: {
list: [1,2,3,4,5,6,7,8,9,10]
},
getters: {
// getters函数的第一个参数是 state
// 必须要有返回值
filterList: state => (n)=>state.list.filter(item => item > n)
}
===通过函数每次都进行调用不会缓存===
原始调用
<div>{{ $store.getters.filterList }}</div>
<div>{{ $store.getters.filterList(5) }}</div>
结合 computed
computed: {
filterList () {
return this.$store.getters.filterList
}
}
辅助函数 mapGetters
computed: {
...mapGetters(['filterList'])
}
// 重命名
computed: {
...mapGetters({filterListAlias:'filterList'})
}
// ...
<div>{{ filterList }}</div>
mutations
state数据的修改只能通过mutations,并且mutations必须是同步更新, 不能写异步代码 (比如axios)
mutations是一个对象,对象中存放修改state的方法
mutations: {
// 方法里参数 第一个参数是当前store的state属性
// 第二个可选参数payload, 载荷 运输参数, 外部调用mutaiions的时候可以传递参数
addCount (state, data) {
state.count += data
}
},
this.$store.commit
// 调用方法
//...
<button @click="addCount(666)">+</button>
//...
methods: {
addCount(num){
this.$store.commit('addCount', num) // commit 提交
}
}
mapMutations
mapMutations和mapState很像,它把位于mutations中的方法提取了出来,我们可以将它导入
import { mapMutations } from 'vuex'
methods: {
...mapMutations(['addCount']),
}
// 对像写法, 重命名
methods: {
...mapMutations({changeAllDistrictAlias:'changeAllDistrict'})
}
actions
state是存放数据的,mutations是同步更新数据,actions则负责进行异步操作(比如请求, 定时器)
// 定义actions
actions: {
// 第一个参数context表示当前的store的实例,可以通过 context.state 获取状态,也可以通过context.commit 来提交mutations,也可以 context.dispatch调用其他的action
// 第二个参数data 可选
getAsyncCount (context) { // 这里可以用解构 getAsyncCount({ commit })
setTimeout(function(){
context.commit('addCount', 123) // 对应的可以简写 commit('addCount', 123)
}, 1000)
},
// 写法2
getAsyncCount ({commit}) {
setTimeout(function(){
commit('addCount', 123)
}, 1000)
},
}
原始调用
addAsyncCount () {
this.$store.dispatch('getAsyncCount') // dispatch 委派
}
// 传参
addAsyncCount () {
this.$store.dispatch('getAsyncCount', 123)
}
mapActions
actions也有辅助函数,可以将action导入到组件中
import { mapActions } from 'vuex'
methods: {
...mapActions(['getAsyncCount'])
}
// 重命名
methods: {
...mapActions({ initialDistrictAlias: 'initialDistrict' })
}
直接通过 this.方法就可以调用
<button @click="getAsyncCount(111)">+异步</button>
Module
每个子模块都是一个对象, 可以自己拥有state, mutations, actions, getters
const store = new Vuex.Store({
modules: {
user: {
state: {
token: '12345'
}
},
setting: {
state: {
name: 'Vuex实例'
}
}
})
原始调用
// store.state.模块名.字段名
<template>
<div>
<div>用户token {{ $store.state.user.token }}</div>
<div>网站名称 {{ $store.state.setting.name }}</div>
</div>
</template>
配合 getters + mapGetters
// 配合getters简写
getters: {
token: state => state.user.token,
name: state => state.setting.name
}
// 再配合mapGetters
computed: {
...mapGetters(['token', 'name'])
}
命名空间
==注意: 默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的==(简单的说不加模块名直接带上字段名就可以调用 state.token) , 为了保证内部模块的高封闭性,采用namespaced来进行设置
user: {
namespaced: true, // 命名空间
state: {
token: '12345'
},
mutations: {
// 这里的state表示的是user的state
updateToken (state) {
state.token = 678910
}
}
},
方案1:带上模块的属性名路径
// 对于有命名空间的action和mutation, 要带上 '命名空间/模块名'
methods: {
...mapMutations(['user/updateToken']),
test () {
this['user/updateToken']()
}
}
<button @click="test">修改token</button>
// 调用模块里的mutatios/actions
this.$store.dispatch('user/getUserInfo')
this.$store.commit('user/getUserInfo')
computed: {
// 把模块名字符串当成第一个参数传进去
...mapState('some/nested/module', {
a: state => state.a,
b: state => state.b
})
},
methods: {
...mapActions('some/nested/module', [
'foo',
'bar'
])
}
方案2: createNamespacedHelpers 创建基于某个命名空间辅助函数
import { mapGetters, createNamespacedHelpers } from 'vuex'
// ...
const { mapMutations: mapMutationsUser } = createNamespacedHelpers('user') //创建出属于当前模块的辅助函数, 是一个对象, 里面包括mapGetters, mapState, mapMutations
// 解构并重命名
export default {
computed: {
...mapGetters(['token', 'appName']) // 这里就是子模块里的
},
methods: {
...mapMutationsUser(['setUserInfo'])
}
}
<button @click="updateToken">修改token2</button>
持久化
VuexPersistence
https://www.npmjs.com/package/vuex-persist
https://www.cnblogs.com/lemoncool/p/9645587.html
Steps
Import it
import VuexPersistence from 'vuex-persist'
NOTE: In browsers, you can directly use
window.VuexPersistence
Create an object
const vuexLocal = new VuexPersistence({
storage: window.localStorage
})
Use it as Vue plugin.
const store = {
state: { ... },
mutations: { ... },
actions: { ... },
plugins: [vuexLocal.plugin]
}
vuex-persist 的详细属性:
属性 | 类型 | 描述 |
---|---|---|
key | string | 将状态存储在存储中的键。默认: 'vuex' |
storage | Storage (Web API) | 可传localStorage, sessionStorage, localforage 或者你自定义的存储对象. 接口必须要有get和set. 默认是: window.localStorage |
saveState | function (key, state[, storage]) | 如果不使用存储,这个自定义函数将保存状态保存为持久性。 |
restoreState | function (key[, storage]) => state | 如果不使用存储,这个自定义函数处理从存储中检索状态 |
reducer | function (state) => object | 将状态减少到只需要保存的值。默认情况下,保存整个状态。 |
filter | function (mutation) => boolean | 突变筛选。看mutation.type并返回true,只有那些你想坚持写被触发。所有突变的默认返回值为true。 |
modules | string[] | 要持久化的模块列表。 |
总结
- state 仓库状态对象
- mutations 改变数据的函数, 同步
- action 异步函数
- getters 类似计算属性的数据获取
- modules 子模块