一,前言
上一篇,介绍了 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.Store
const 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 状态的实现;
评论