概念Vuex是一个专为Vue.js应用程序开发的状态管理模式。当项目比较庞大的时候,每个组件的状态很多,为了方便管理,需要把组件中的状态抽取出来,放入Vuex中进行统一管理。每一个 Vuex 应用的核心就是store(仓库)。“store"基本上就是一个容器,它包含着你的应用中大部分的状态(state)。Vuex 和单纯的全局对象有以下两点不同:Vuex的状态存储是响应式的。当 Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会相应地得到高效更新。你不能直接改变store中的状态。改变store中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。简单应用构建vue工程vue init webpack vuexStudy构建后目录结构其中:index.jsimport Vue from ‘vue’import Vuex from ‘vuex’//如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)Vue.use(Vuex);export default new Vuex.Store({ state: { //存放组件之间共享的数据 //在组件通过this.$store.state.count获取 count: 0 }, mutations: { //显式的更改state里的数据,不能用于处理异步事件 //组件中通过this.$store.commit(‘incrementByStep’);调用 incrementByStep(state) { state.count++; } }, getters:{ //如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关性计算 }, actions:{ //类似于mutation,用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步操作 }});new Vuex.Store({}) 表示创建一个Vuex实例,通常情况下,他需要注入到Vue实例里。 Store是Vuex的一个核心方法,字面上理解为“仓库”的意思。Vuex Store是响应式的,当Vue组件从store中读取状态(state选项)时,若store中的状态发生更新时,他会及时的响应给其他的组件而且不能直接改变store的状态,改变状态的唯一方法是显式地提交更改。main.js引入vueximport Vue from ‘vue’import App from ‘./App’//vuex文件import store from ‘./store’Vue.config.productionTip = false;/* eslint-disable no-new */new Vue({ el: ‘#app’, //引入 store, components: { App }, template: ‘<App/>’})APP.vue引用了counter这个组件 <div id=“app”> <!–<img src=”./assets/logo.png">–> <!–<HelloWorld/>–> <counter/> </div></template><script>import HelloWorld from ‘./components/HelloWorld’import counter from ‘./components/counter’export default { name: ‘App’, components: { //HelloWorld counter }}</script><style>#app { font-family: ‘Avenir’, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px;}</style>counter.vue定义counter组件<template> <div id=“counterContent”> <div>{{ count }}</div> <button v-on:click=“addCount”>请点击</button> </div></template><script> export default { name: “counter”, computed: { count () { return this.$store.state.count } }, methods:{ addCount(){ debugger; this.$store.commit(‘incrementByStep’); } } }</script><style scoped> #counterContent{ background-color: blue; width:200px; height:50px; }</style>通过npm run dev启动项目,最终的结果如图:源码解读node添加Vuex依赖下载的vuex文件(node_modules目录下)如下:其中vuex.common.js在预编译调试时,CommonJS规范的格式,可以使用require("")引用的NODEJS格式。vuex.esm.js在预编译调试时, EcmaScript Module(ES MODULE),支持import from 最新标准的。vuex.js直接用在<script>标签中的,完整版本,直接就可以通过script引用。而vuex的源码托管在https://github.com/vuejs/vuex,这里研究git上的源码。入口Vuex 源码的入口是 src/index.js。import { Store, install } from ‘./store’import { mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers } from ‘./helpers’export default { Store, install, version: ‘VERSION’, mapState, mapMutations, mapGetters, mapActions, createNamespacedHelpers}这是Vuex对外暴露的API。其中, Store是Vuex提供的状态存储类,通常我们使用Vuex就是通过创建 Store的实例。接着是install方法,这个方法通常是我们编写第三方Vue插件的时候使用。installinstall是在store.js内暴露的方法当Vue通过npm安装到项目中的时候,我们在代码中引入第三方Vue插件需要添加下列代码import Vue from ‘vue’import Vuex from ‘vuex’//如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)Vue.use(Vuex);执行Vue.use(Vuex)的时候,其实就是调用了install的方法并传入Vue的引用。Vue.use Vue.use = function (plugin) { var installedPlugins = (this._installedPlugins || (this._installedPlugins = [])); if (installedPlugins.indexOf(plugin) > -1) { return this } // additional parameters var args = toArray(arguments, 1); args.unshift(this); if (typeof plugin.install === ‘function’) { //调用vuex的install plugin.install.apply(plugin, args); } else if (typeof plugin === ‘function’) { plugin.apply(null, args); } installedPlugins.push(plugin); return this };}install //判断Vue是否已存在,保证install方法只执行一次 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变量,index.js文件的其它地方使用Vue这个变量 Vue = _Vue //调用了 applyMixin 方法,给 Vue 的实例注入一个 $store 的属性 applyMixin(Vue)}plugin参数:args参数:var applyMixin = function (Vue) { //获取版本信息,这里是2 var version = Number(Vue.version.split(’.’)[0]); if (version >= 2) { //调用vuexInit Vue.mixin({ beforeCreate: vuexInit }); } else { var _init = Vue.prototype._init; Vue.prototype._init = function (options) { if ( options === void 0 ) options = {}; options.init = options.init ? [vuexInit].concat(options.init) : vuexInit; _init.call(this, options); }; } //给Vue实例注入$store 的属性,可以通过this.$store.xxx访问 function vuexInit () { var options = this.$options; // store injection if (options.store) { this.$store = typeof options.store === ‘function’ ? options.store() : options.store; } else if (options.parent && options.parent.$store) { this.$store = options.parent.$store; } }};