vuex: 状态管理模式,集中式存储管理应用的所有组件的状态。用于多组件通信。
优点:数据存储方便、数据流动清晰、数据是响应式、代码结构化且易维护。
1、传输流程
dispatch触发actions方法—commit触发mutations—在mutation里面进行state修改—页面变化
2、安装与配置
- 安装:npm install vuex@3.6.2
- 实例化store 根目录/src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
modules:{}
getters:{}
state: {},
mutations: {},
actions: {}
})
- 注册vue实例 main.js
import store from './store'
new Vue({
// 省略其他...
store
})
- 使用:this.$store.state
3、核心属性
- state:定义统一数据,与data类似
- mutations:更改vuex中状态的唯一方法,通过commit触发,同步任务,与methods类似
- actions:包含异步任务,提交到mutation执行
- modules:模块拆分
- getters:类似computed,只有依赖值发生变化才会重新计算
state: 定义数据
// 定义、声明变量
state: {
name:"张三",
age:12,
},
// 调用
// 方式一:标签使用
<p>{{$store.state.name}</p>
// 方式二:方法调用
this.$store.state.name
// 方式三:辅助函数mapState
import { mapState } from "vuex" // 按需引入
computed: {
...mapState(['name','age'])
}
<p>{{name+age}}</p>
mutations:修改数据,更改store状态唯一方法
// 定义、声明变量
state: {
count:0
},
mutations:{
//每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)
//这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数
add(state,num){
state.count+=num
},
reduce(state){
state.count--
}
}
// 调用
// 方式一:commit触发
methods:{
btn(){
this.$store.commit("add",1)
}
}
// 方式二:辅助函数mapMutations
import { mapMutations} from "vuex" // 按需引入
methods: {
...mapMutations(['add','reduce']),
btn(){
this.add(1)
}
}
actions:异步操作,提交给mutation执行
// 定义、声明变量
state: {
count:0
},
actions:{
// 方式一:context
reduceAsync(context){
setTimeout(()=>{
context.commit("reduce")
},1000)
},
// 方式二:直接commit
addAsync({commit},num){
setTimeout(()=>{
commit("add",num)
},1000)
}
}
// 调用
// 方式一:dispatch触发
this.$store.dispatch("reduceAsync")
// 方式二:辅助函数mapActions
import { mapActions} from "vuex" // 按需引入
methods: {
...mapActions(['reduceAsync']),
btn(){
this.reduceAsync()
}
}
getters:计算属性,对store中数据进行处理加工
state: {
age:10
},
getters:{
getAge(state){ // 只有state一个参数
return state+='岁'
}
}
// 使用:
// 方式一:标签使用
<p>{{$store.getters.getAge}</p>
// 方式二:放入computed
computed:{
age(){
return this.$store.getters.getAge
}
}
<p>{{age}}</p>
// 方式三:辅助函数mapGetters
import { mapGetters} from "vuex" // 按需引入
computed: {
...mapGetters(['getAge'])
}
<p>{{getAge}}</p>
modules:拆分模块,每个模块有独立的state、mutations、actions、getters、modules(嵌套子模块)
modules:{
ageModules:{
state:{ age:10},
mutations:{
changeAge(state){
state.age=20
}
}
},
nameModules:{
state:{name:'张三'}
// 省略的mutations、actions、getters、modules
}
}
// 使用
this.$store.state.nameModules.name
补充说明:模块创建后,可动态注册、动态卸载模块
// 动态注册模块---使用同上
store.registerModule('moduleName',{
//........
})
// 动态注销模块----对于静态模块无效,
store.unregisterModule(moduleName)
4、actions与mutations的区别
- mutations修改state的唯一途径,actions不能直接修改state
- mutations 同步操作,actions 异步任务
- actions触发后,会提交给mutations来修改state状态
- mutations 参数是state;actions的参数是context,包含state和getters
补充说明:mutation为何不能是异步?
每个mutation执行完会得到一个状态变更,devtools会打快照存起来,可以实现time-travel,可以跟踪一个状态的变化,若为异步,则无法进行状态追踪
5、vuex 与localStorage区别
- vuex 存内存; localStorage存浏览器
- vuex能做数据的响应式,localStorage不能
- vuex一般用于组件间传值,localStorage用于跨页面传参
- vuex刷新会丢失,localStorage不会
补充说明:vuex刷新后数据丢失怎么处理?----用sessionStorage、localStorage存储
6、vuex 与redux的区别
vuex 弱化了dispatch,弱化reducer基于commit直接对数据修改
共同思想:单一数据源、变化可监测
7、vuex严格模式、namespaced作用
严格模式:状态变更不是mutation操作的,会抛出错误(便于状态变更被调试工具追踪到)
开启严格模式:
export default new Vuex.Store({
strict:true
})
namespaced:模块管理时防止不同模块命名冲突、可设置namespaced:true
// 模块A
//....省略代码
export default {
namespaced: true,
state,
getters,
actions,
mutations
}
// 调用:
// store.state.模块名.属性
this.$store.state.moduleA.name
// 模块名/模块中mutation
this.$store.commit("moduleA/add",10)
// 模块名/模块中action
this.$store.dispatch("moduleA/addAsync",10)
// 模块名/模块中getter
this.$store.getters.moduleA.getAge
8、vuex辅助函数(重复使用state、getters、mutations、actions)
mapState、mapGetters、mapMutations、mapActions
详见3的示例