了解Vuex4.x 简单实现原理
2021/9/16 23:35:39
本文主要是介绍了解Vuex4.x 简单实现原理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
参考文档:
- Vuex4.x官方文档
Vuex是什么
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
这个状态自管理应用包含以下几个部分:
- 状态,驱动应用的数据源;
- 视图,以声明方式将状态映射到视图;
- 操作,响应在视图上的用户输入导致的状态变化。
Vuex的工作原理如下图所示:
Vuex4.x的简单用法
创建一个 store 实例
import { createApp } from 'vue' import { createStore } from 'vuex' // 创建一个新的 store 实例 const store = createStore({ state () { return { count: 0 } }, getters: { double(state){ return state.count * 2 } }, mutations: { increment (state, payload) { state.count++ } }, actions: { AsyncIncrement(state, payload){ return new Promise((resolve, reject) => { setTimeout(() => { commit('someMutation', payload) resolve() }, 1000) }) } } }) const app = createApp({ /* 根组件 */ }) // 将 store 实例作为插件安装 app.use(store)
通过组合式API的方法使用
访问 State 和 Getter
import { computed } from 'vue' import { useStore } from 'vuex' export default { setup () { const store = useStore() return { // 在 computed 函数中访问 state count: computed(() => store.state.count), // 在 computed 函数中访问 getter double: computed(() => store.getters.double) } } }
访问 Mutation 和 Action
import { useStore } from 'vuex' export default { setup () { const store = useStore() return { // 使用 mutation increment: () => store.commit('increment'), // 使用 action asyncIncrement: () => store.dispatch('asyncIncrement') } } }
从用法上对比Vuex3.x
- 创建
store
的方法不同,之前是通过new Store()
来创建一个store
实例。现在是通过createStore
方法来创建。 - Vuex4.x兼容之前的使用方法。但是在Vue3.x中如果我们想要通过组合式API的方法使用Vuex,我们需要借助与
useStore
这个函数。
实现一个简单的 Vuex4.x;
实现一个 createStore
方法
store实际上还是基于一个Class
来实现的,只是没有直接将 Store
这个类暴露出来,而是包装成了一个函数,直接返回实例。
import { reactive } from 'vue' export function createStore(options){ return new Store(options) } class Store{ constructor(options){ const store = this; // 使用reactive使state是响应式的 store._state = reactive({data: options.state}) } get state(){ return this._state.data } }
通过 Object.defineProperty
来重新定义getters
将用户传入的getters
全部定义到store实例的getters属性上,在获取值的时候调用
function forEachValue(obj, fn){ Object.keys(obj).forEach(key => fn(obj[key], key)) } class Store{ constructor(options){ const store = this; // 使用reactive使state是响应式的 store._state = reactive({data: options.state}) // 保存getters const _getters = options.getters; store.getters = {}; forEachValue(_getters, function(fn, key){ Object.defineProperty(store.getters, key, { get: ()=> fn(store.state), enumerable: true }) }) } }
基于发布订阅模式实现 mutations
和 actions
class Store{ constructor(options){ // ... const store = this; store._mutations = Object.create(null) const _mutations = options.mutations; forEachValue(_mutations, (mutation, key)=>{ store._mutations[key] = (payload) => { mutation.call(store, store.state, payload) } }) } commit = (type, payload) => { this._mutations[type](payload) } }
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作
由于action可以执行异步函数,所以action在执行完成后应该返回一个Promise实例,对dispact的执行结果进行判断,如果不是一个Promise,需要给处理成一个promise。
class Store{ constructor(options){ // ... const store = this; store._actions = Object.create(null) const _actions = options.actions; forEachValue(_actions, (action, key)=>{ store._actions[key] = (payload) => { const res = action.call(store, store.state, payload) if(!isPromise(res)){ return Promise.resolve(res) } return res } }) } dispatch = (type, payload) => { this._actions[type](payload) } }
useStore
通过inject
来获取注册的store实例
import {inject} from 'vue' export function useStore(injectKey = null) { return inject('store') }
install
在Vue项目中使用Vuex,我们需要通过use()
来注册store
const app = createApp({ /* 根组件 */ }) // 将 store 实例作为插件安装 app.use(store)
class Store{ install(app, injectKey){ // Vue3.x createApp().use(store) // 全局暴露一个 变量,暴露的是store的实例 app.provide('store') // Vue2.x Vue.prototype.$store = this // 增添$store属性 使得可以直接在模板中使用 $store.state.count app.config.globalProperties.$store = this; } }
这篇关于了解Vuex4.x 简单实现原理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-19vue2 开发移动端h5 使用那个ui框架比较好?-icode9专业技术文章分享
- 2024-11-19ReactJS结合TypeScript、Vite、Redux和TanStack (React Query) 实战教程
- 2024-11-19Vue3资料入门教程:零基础快速上手指南
- 2024-11-19Vue3资料:新手入门教程与实战指南
- 2024-11-19Vue资料:新手入门vue.js教程与实践指南
- 2024-11-19Vue资料:初学者入门指南
- 2024-11-18tcpdf可以等待vue动态页面加载完成后再生成pdf吗?-icode9专业技术文章分享
- 2024-11-16Vue3资料:新手入门必读教程
- 2024-11-16Vue3资料:新手入门全面指南
- 2024-11-16Vue资料:新手入门完全指南