vuex实现及简略解析(小结)

大家都知道vuex是vue的一个状态管理器,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。先看看vuex下面的工作流程图

vuex实现及简略解析(小结)


通过官方文档提供的流程图我们知道,vuex的工作流程,

1、数据从state中渲染到页面;

2、在页面通过dispatch来触发action;

3、action通过调用commit,来触发mutation;

4、mutation来更改数据,数据变更之后会触发dep对象的notify,通知所有Watcher对象去修改对应视图(vue的双向数据绑定原理)。

使用vuex

理解vuex的工作流程我们就看看vuex在vue中是怎么使用的。

首先用vue-cli创建一个项目工程,如下图,选择vuex,然后就是一路的回车键

vuex实现及简略解析(小结)

安装好之后,就有一个带有vuex的vue项目了。

进入目录然后看到,src/store.js,在里面加了一个状态{count: 100},如下

import Vue from 'vue' import Vuex from 'vuex' // 引入vuex Vue.use(Vuex) // 使用插件 export default new Vuex.Store({ state: { count: 100 // 加一个状态 }, getter: { }, mutations: { }, actions: { } })

最后在App.vue文件里面使用上这个状态,如下

<template> <div> 这里是stort------->{{this.$store.state.count}} </div> </template> <script> export default { name: 'app' } </script> <style> </style>

项目跑起来就会看到页面上看到,页面上会有100了,如下图

vuex实现及简略解析(小结)

到这里我们使用vuex创建了一个store,并且在我们的App组件视图中使用,但是我们会有一些列的疑问。

store是如何被使用到各个组件上的??

为什么state的数据是双向绑定的??

在组件中为什么用this.$store.dispch可以触发store的actions??

在组件中为什么用this.$store.commit可以触发store的mutations??

....等等等等

带着一堆问题,我们来自己实现一个vuex,来理解vuex的工作原理。

安装并使用store

在src下新建一个vuex.js文件,然后代码如下

'use strict' let Vue = null class Store { constructor (options) { let { state, getters, actions, mutations } = options } } // Vue.use(Vuex) const install = _Vue => { // 避免vuex重复安装 if (Vue === _Vue) return Vue = _Vue Vue.mixin({ // 通过mixins让每个组件实例化的时候都会执行下面的beforeCreate beforeCreate () { // 只有跟节点才有store配置,所以这里只走一次 if (this.$options && this.$options.store) { this.$store = this.$options.store } else if (this.$parent && this.$parent.$store) { // 子组件深度优先 父 --> 子---> 孙子 this.$store = this.$parent.$store } } }) } export default { install, Store }

然后修改store.js中的引入vuex模块改成自己的vuex.js

import Vuex from './vuex' // 自己创建的vuex文件

在我们的代码中export default { install, Store }导出了一个对象,分别是install和Store

install的作用是,当Vue.use(Vuex)就会自动调用install方法,在install方法里面,我们用mixin混入了一个beforeCreate的生命周期的钩子函数,使得当每个组件实例化的时候都会调用这个函数。

在beforeCreate中,第一次根组件通过store属性挂载$store,后面子组件调用beforeCreate挂载的$store都会向上找到父级的$store,这样子通过层层向上寻找,让每个组件都挂上了一个$store属性,而这个属性的值就是我们的new Store({...})的实例。如下图

vuex实现及简略解析(小结)

通过层层向上寻找,让每个组件都挂上了一个$store属性

设置state响应数据

通过上面,我们已经从每个组件都通过this.$store来访问到我们的store的实例,下面我们就编写state数据,让其变成双向绑定的数据。下面我们改写store类

class Store { constructor (options) { let { state, getters, actions, mutations } = options // 拿到传进来的参数 this.getters = {} this.mutations = {} this.actions = {} // vuex的核心就是借用vue的实例,因为vuex的数据更改回更新视图 this._vm = new Vue({ data: { state } }) } // 访问state对象时候,就直接返回响应式的数据 get state() { // Object.defineProperty get 同理 return this._vm.state } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/bbaa321d0423eb4ae26a0b8c107760a4.html