状态管理:本质对一个[全局唯一、具有响应式]变量的管理
因为是全局的,那为了流转/使用上的不混乱/冲突等,所以会对其制定流转规则,让变化变得可预测
Vuex:
状态流转:actions => mutations => state
state:数据的存储
mutations:唯一的对数据的[同步]操作(增删改查)入口,可以做简单的业务处理
actions:复杂业务逻辑处理(axios 等)的入口,并只能调用 mutations
Vuex 3.x
使用:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
原理:
- 其中的
Store本质是类,所以才new Vuex.Store({ /*...*/ }) - 通过
Vue.use(Vuex),调用Vuex的install方法
-
install方法里面写了Vue.mixin({ beforeCreate: vuexInit })
-
-
- 所以
Vuex的注入是通过Vue.mixin()混入beforeCreate方法实现
- 所以
-
-
- 并且在
vuexInit内,定义了this.$store,实现$store的挂载
- 并且在
- 通过借用
Vue本身实现Vuex的响应式,并且this.$store.state的获取是通过get实现的
export class Store {
constructor (options = {}) {
// ......
resetStoreVM(this, state)
},
// ......
get state () {
return this._vm._data.$$state
}
// ......
}
function resetStoreVM(store, state)
// ......
// ⭐️ 实现 Vuex 的响应式
store._vm = new Vue({
data: {
$$state: state
},
computed
}
// ......
})
Vuex 4.x
官方文档:vuex.vuejs.org/zh/
使用:
import { createApp } from 'vue'
import { createStore } from 'vuex'
/*
function createStore (options) {
return new Store(options)
}
*/
// 创建一个新的 store 实例
const store = createStore({
state () {
return {
count: 0
}
},
mutations: {
increment (state) {
state.count++
}
}
})
const app = createApp({ /* 根组件 */ })
// 将 store 实例作为插件安装
app.use(store)
原理:
- 引入的
createStore本质是个生成实例的函数 - 通过
app.use(store),调用store 实例的install方法
-
install方法里面写了vue.provide(storeKey, this)
-
-
- 所以
Vuex的注入是通过vue.provide()实现的 - 并且还定义了
vue.config.globalProperties.$store = this,实现$store的挂载
- 所以
-
- 通过借用
Vue的reactive实现Vuex的响应式,并且this.$store.state的获取是通过get实现的
import { reactive } from 'vue'
export class Store {
constructor (options = {}) {
// ......
resetStoreState(this, state)
},
install (vue, injectKey) {
vue.provide(injectKey || storeKey, this)
vue.config.globalProperties.$store = this
}
// ......
get state () {
return this._state.data
}
// ......
}
function resetStoreState(store, state)
// ......
// ⭐️ 实现 Vuex 的响应式
store._state = reactive({
data: state
})
// ......
})
Pinia:
官方文档:pinia.vuejs.org/zh/introduc…
原理:
跟 Vuex 4.x 差不多的
使用了vue的provide/inject、vue.config.globalProperties.$store、reactive等
其他补充
观察者 & 发布订阅
观察者:不存在一个中心,事件流:A => B
A 干了xxx,B 观察到了,就直接再行动。
Vue 就是观察者模式,通过拦截数据的读取操作,收集依赖;拦截数据的设置操作,触发依赖
发布订阅:存在一个中心,事件流为:A => 中心 => B
A 干了xxx,然后通知事件中心,事件中心再去通知对应的订阅者(B),B 再行动
EventBus 就是发布订阅