-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
582 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
--- | ||
layout: post | ||
title: 3.1.Vuex简要介绍和源码说明 | ||
category: 写教程 | ||
tag: vuex | ||
exception: | ||
readtime: 5 | ||
--- | ||
|
||
## vuex简介 | ||
* Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 | ||
* 直白一点,vuex就是把组件的共享状态抽取出来,以一个全局单例模式管理的数据仓库,里面提供了对应用的数据存储和对数据的操作,维护整个应用的公共数据。 | ||
|
||
## vuex源码结构 | ||
* 我们使用git工具下载最新的vuex源码([https://github.com/vuejs/vuex.git](https://github.com/vuejs/vuex.git))。 目前最新的版本3.1.1,后面的代码分析都使用该版本。 | ||
* 我们先大致看一下vuex项目的目录结构: | ||
 | ||
* 对目录的一些简要说明如下: | ||
├ build // 编译配置目录 | ||
├ dist // 打包后的文件目录 | ||
├ docs // 文档源码目录 | ||
├ docs-gitbook // 文档gitbook版目录 | ||
├ examples // 功能示例目录 | ||
├ src // 功能源码目录 | ||
├ test // 代码测试目录 | ||
└ types // types类型文件目录 | ||
* 其中我们重点要分析的就是src源码目录代码和examples示例目录代码。 | ||
|
||
## vuex解析要点 | ||
* 这里我们先看看vuex项目的src源码目录 | ||
 | ||
* 对目录文件的一些简要说明如下: | ||
src | ||
├ module //模块管理目录 | ||
│ ├ module-collection.js //创建组模块树 | ||
│ └ module.js //创建模块 | ||
│ | ||
├ plugins //插件目录目录 | ||
│ ├ devtool.js //开发工具插件 | ||
│ └ logger.js //日志插件 | ||
│ | ||
├ helpers.js //mapSate,mapMutations,mapActions,mapGetters 等操作函数 | ||
├ index.esm.js //入口文件,用于es-module打包 | ||
├ index.js //入口文件,用于commonjs打包 | ||
├ mixin.js //注入方法,将store挂载到vue实例 | ||
├ store.js //核心代码,创建store对象 | ||
└ util.js //工具类,deepClone、isPromise等函数 | ||
* 我们先大致了解下每个文件的作用说明。 | ||
|
||
## 小结 | ||
使用过vuex的朋友肯定都知道,vuex的核心其实就是state、getter、mutation、action、module这五大部分。接下来,我们将主要围绕这些核心东西来解析vuex的源码。 | ||
|
||
## 参考 | ||
* [https://vuex.vuejs.org/zh/](https://vuex.vuejs.org/zh/) | ||
* [https://segmentfault.com/a/1190000014363436](https://segmentfault.com/a/1190000014363436) | ||
* [https://www.cnblogs.com/chenmeng2062/p/9337650.html](https://www.cnblogs.com/chenmeng2062/p/9337650.html) | ||
* [https://blog.csdn.net/sinat_17775997/article/details/62231288](https://blog.csdn.net/sinat_17775997/article/details/62231288) | ||
* [https://www.cnblogs.com/caizhenbo/p/7380200.html](https://www.cnblogs.com/caizhenbo/p/7380200.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
--- | ||
layout: post | ||
title: 3.2.Vuex安装使用分析 | ||
category: 写教程 | ||
tag: vuex | ||
exception: | ||
readtime: 10 | ||
--- | ||
|
||
## 使用示例 | ||
* 我们先来看看vuex官方给的一个简单示例。 | ||
|
||
```vuejs | ||
import Vue from 'vue' | ||
import Vuex from 'vuex' | ||
//注册vuex插件 | ||
Vue.use(Vuex) | ||
// root state object. | ||
// each Vuex instance is just a single state tree. | ||
//定义state | ||
const state = { | ||
count: 0 | ||
} | ||
// mutations are operations that actually mutates the state. | ||
// each mutation handler gets the entire state tree as the | ||
// first argument, followed by additional payload arguments. | ||
// mutations must be synchronous and can be recorded by plugins | ||
// for debugging purposes. | ||
//定义mutations | ||
const mutations = { | ||
increment (state) { | ||
state.count++ | ||
}, | ||
decrement (state) { | ||
state.count-- | ||
} | ||
} | ||
// actions are functions that cause side effects and can involve | ||
// asynchronous operations. | ||
//定义actions | ||
const actions = { | ||
increment: ({ commit }) => commit('increment'), | ||
decrement: ({ commit }) => commit('decrement'), | ||
incrementIfOdd ({ commit, state }) { | ||
if ((state.count + 1) % 2 === 0) { | ||
commit('increment') | ||
} | ||
}, | ||
incrementAsync ({ commit }) { | ||
return new Promise((resolve, reject) => { | ||
setTimeout(() => { | ||
commit('increment') | ||
resolve() | ||
}, 1000) | ||
}) | ||
} | ||
} | ||
// getters are functions | ||
//定义getters | ||
const getters = { | ||
evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd' | ||
} | ||
// A Vuex instance is created by combining the state, mutations, actions, | ||
// and getters. | ||
//导出vuex实例 | ||
export default new Vuex.Store({ | ||
state, | ||
getters, | ||
actions, | ||
mutations | ||
}) | ||
``` | ||
* 首先注册vuex插件 | ||
```vuejs | ||
import Vue from 'vue' | ||
import Vuex from 'vuex' | ||
Vue.use(Vuex) | ||
``` | ||
* 然后分别定义state、mutations、actions、getters,并导出 | ||
* 最后将vuex对象实例挂载到vue的每一个实例上去 | ||
```vuejs | ||
new Vue({ | ||
el: '#root', | ||
router, | ||
store, | ||
render: h => h(App) | ||
}) | ||
``` | ||
|
||
## vuex的安装 | ||
* vuex作为vue的一个插件,在使用插件vue.use(vuex)时,会通过vuex对象中的install方法将vuex载入,现在我们来看看install方法的实现。 | ||
* install方法在store.js文件中 | ||
```vuejs | ||
export function install (_Vue) { | ||
//这里使用全局变量Vue进行判断,避免重复安装 | ||
if (Vue && _Vue === Vue) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
console.error( | ||
'[vuex] already installed. Vue.use(Vuex) should be called only once.' | ||
) | ||
} | ||
return | ||
} | ||
Vue = _Vue | ||
//重点在这里 | ||
applyMixin(Vue) | ||
} | ||
``` | ||
* 这里只是用全局变量做了下判断,避免重复安装,其重点还在最后调用的applyMixin(Vue)函数上 | ||
* 我们来看看applyMixin函数,在mixin.js文件中 | ||
```vuejs | ||
export default function (Vue) { | ||
const version = Number(Vue.version.split('.')[0]) | ||
if (version >= 2) { | ||
//在2.x.x以上版本,直接使用hook的形式进行注入 | ||
Vue.mixin({ beforeCreate: vuexInit }) | ||
} else { | ||
// override init and inject vuex init procedure | ||
// for 1.x backwards compatibility. | ||
//在2.x.x一下版本,使用封装并替换Vue对象原型的_init方法,实现注入 | ||
const _init = Vue.prototype._init | ||
Vue.prototype._init = function (options = {}) { | ||
options.init = options.init | ||
? [vuexInit].concat(options.init) | ||
: vuexInit | ||
_init.call(this, options) | ||
} | ||
} | ||
/** | ||
* Vuex init hook, injected into each instances init hooks list. | ||
*/ | ||
function vuexInit () { | ||
const options = this.$options | ||
// store injection | ||
if (options.store) { | ||
//根组件就直接设置到this对象的$store属性上 | ||
this.$store = typeof options.store === 'function' | ||
? options.store() | ||
: options.store | ||
} else if (options.parent && options.parent.$store) { | ||
//子组件从其父组件引用$store属性,层层嵌套进行设置 | ||
this.$store = options.parent.$store | ||
} | ||
} | ||
} | ||
``` | ||
* 在安装注入函数时会判断vue的版本,2.x.x以上版本,使用 hook 的形式进行注入,而低于2.x.时使用封装并替换Vue对象原型的_init方法,实现注入。 | ||
* 注入的函数实现的功能其实就是当vuex设置到vue对象的$store属性上,便于在任意组件中执行 this.$store 都能找到装载的那个store对象。 | ||
这里它会判断设置的是根组件还是非根组件,根组件时直接设置到this对象的$store属性上,子组件则从其父组件引用$store属性,层层嵌套进行设置。 | ||
* 到此,vuex的安装工作就已经完成了。 | ||
|
||
## 小结 | ||
* 这一节我们只是简单的看了一下vuex的使用方式,顺便解析了下vuex安装注入到vue实例上的过程。下节我们将进入vuex的核心内容。 |
Oops, something went wrong.