一,前言
上一篇,介绍了 vuex 的基本用法,主要包含以下几个点:
vuex 项目创建;
vuex 工作流程介绍;
vuex 的基本使用介绍;
本篇,继续介绍 vuex 的 install 插件安装逻辑;
二,vuex 插件安装逻辑的实现
1,前文回顾
上一篇,在介绍 vuex 的基本用法前,先安装了 vuex 插件,并进行了相关的配置:
// src/store/index.js
import Vue from 'vue';import Vuex from 'vuex';
// 注册 vuex 插件:内部会调用 Vuex 中的 install 方法Vue.use(Vuex);
// 实例化容器容器:Vuex.Storeconst store = new Vuex.Store({ ...});
// 导出 store 实例,传入根组件export default store;
复制代码
将 store 实例注入到 vue 中:
// src/main.js
import Vue from 'vue'import App from './App.vue'import store from './store/index' // 引入 store 实例
Vue.config.productionTip = false
new Vue({ store,// 将 store 实例注入到 vue 中 render: h => h(App),}).$mount('#app');
复制代码
使用 vuex:
<template> <div id="app"> 商品数量: {{this.$store.state.num}} 个<br> 商品单价: 10 元<br> 订单金额: {{this.$store.getters.getPrice}} 元<br> <button @click="$store.commit('changeNum',5)">同步更新:数量+5</button> <button @click="$store.dispatch('changeNum',-5)">异步更新:数量-5</button> </div></template>
复制代码
从 Vuex 的使用方式可以看出:
2,创建 vuex 插件
vuex 的以上特点,创建 vuex 目录及入口文件 src/vuex/index.js,其中包含 Store 类和 install 方法并导出:
// 容器的初始化class Store {
}
// 插件安装逻辑:当Vue.use(Vuex)时执行const install =()=>{
}
export default { Store, install}
复制代码
3,模块化设计
所以,这里进行模块化设计,将 Store 类和 install 方法抽离,使 index.js 仅用于方法聚合并导出;
创建 src/vuex/store.js 文件,将 Store 类和 install 方法单独在外部实现并向外导出:
// src/vuex/store.js
// 容器的初始化export class Store {
}
// 插件安装逻辑:当Vue.use(Vuex)时执行export const install =()=>{
}
复制代码
src/vuex/index.js 中,聚合导出的两个方法并导出:
// src/vuex/index.js
import { Store, install } from './store';
export default { Store, install}
复制代码
这样,后续 vuex 插件相关方法可以通过此方式对外导出,如:mapState 等方法;
4,install 插件安装逻辑
vuex 与 vue-router 的插件安装逻辑相似;
当执行Vue.use(Vuex)时,install 方法会传入 vue 的构造函数,实现 vuex 插件与项目使用的 Vue 版本一致:
// src/vuex/store.js
// 导出传入的 Vue 的构造函数,供插件内部的其他文件使用export let Vue;
/** * 插件安装逻辑:当Vue.use(Vuex)时执行 * @param {*} _Vue Vue 的构造函数 */export const install = (_Vue) => { Vue = _Vue;}
复制代码
同时,会将 new Vue 时(根组件)注入的 store 容器实例,混入到所有组件中,为所有组件添加 store 属性:
创建 src/vuex/mixin.js,使用 Vue.mixin 实现全局混入:
// src/vuex/mixin.js
/** * 将根组件中注入store实例,混入到所有子组件上 * @param {*} Vue */export default function applyMixin(Vue) { // 通过 beforeCreate 生命周期,在组件创建前,实现全局混入 Vue.mixin({ beforeCreate: vuexInit,// vuexInit为初始化混入逻辑 });}
复制代码
在 store.js 中引入,并在 install 时调用:
// src/vuex/store.js
import applyMixin from "./mixin";
export const install = (_Vue) => { Vue = _Vue; applyMixin(Vue);}
复制代码
混入逻辑:
由于组件渲染是先渲染父组件再渲染子组件,这样根组件中注入的 store 实例,就可以被混入到 App.vue 组件上。依次类推,由父组件向子组件传递 store 实例,实现全局共享;
function vuexInit() { const options = this.$options; // 如果选项中拥有store属性,说明是根实例;其他情况都是子实例 if (options.store) {// 根实例 // 为根实例添加 $store 属性,指向 store 实例 this.$store = options.store; } else if (options.parent && options.parent.$store) { // 子实例 // 儿子可以通过父亲拿到 $store 属性,放到自己身上继续给儿子 this.$store = options.parent.$store; }}
复制代码
5,测试混入效果
引入新创建的 vuex 作为插件:
// src/store/index.js
import Vue from 'vue';// import Vuex from 'vuex';import Vuex from '@/vuex';
复制代码
在 App.vue 中,打印组件上的 $store 属性,是否混入了来自根组件的 store 实例:
// src/App.vue
<script>export default { mounted(){ console.log(this.$store); }}</script>
复制代码
执行 npm run serve 启动服务:
混入成功!
三,结尾
本篇,介绍了 vuex 的 install 插件安装逻辑,包含以下几个点:
下一篇,介绍 Vuex 中 State 状态的实现;
评论