写点什么

【Vuex 源码学习】第二篇 - vuex 插件安装 install 逻辑

用户头像
Brave
关注
发布于: 1 小时前
【Vuex 源码学习】第二篇 -  vuex 插件安装 install 逻辑

一,前言


上一篇,介绍了 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 的使用方式可以看出:

  • Vuex 是一个对象,内部存在一个 install 方法,当 Vue.use 时执行插件安装逻辑;

  • vuex 中包含了一个 Store 类;

  • 与 vue-router 相似,插件安装时,向所有组件混入了 store 属性;


2,创建 vuex 插件


vuex 的以上特点,创建 vuex 目录及入口文件 src/vuex/index.js,其中包含 Store 类和 install 方法并导出:

// 容器的初始化class Store {
}
// 插件安装逻辑:当Vue.use(Vuex)时执行const install =()=>{
}
export default { Store, install}
复制代码

3,模块化设计


  • Store 类作用:容器的初始化

  • install 方法作用:插件安装逻辑

  • src/vuex/index.js 文件作用:作为 vuex 插件入口,导出方法供外部调用;

所以,这里进行模块化设计,将 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 启动服务:

输出结果:Store {}
复制代码


混入成功!


三,结尾


本篇,介绍了 vuex 的 install 插件安装逻辑,包含以下几个点:


  • 创建 vuex 插件目录;

  • 模块化设计;

  • 实现插件安装 install 时 store 实例混入逻辑;

  • 混入效果测试;


下一篇,介绍 Vuex 中 State 状态的实现;

用户头像

Brave

关注

还未添加个人签名 2018.12.13 加入

还未添加个人简介

评论

发布
暂无评论
【Vuex 源码学习】第二篇 -  vuex 插件安装 install 逻辑