手写一个Vuex,命名为myVuex,替换Vuex的引入,其他使用方法不变。如下内容:
import Vue from 'vue';
import myVuex from '../myVuex';
Vue.use(myVuex);
let store = new myVuex.Store({
state: {
pageSize: 12,
test: '',
ttt: ''
},
// commit
mutations: {
isCommit(state, val) {
state.test = val
}
},
// dispatch
actions: {
isDispatch(state, val) {
state.ttt = val
}
}
})
export default store;
首先,先创建myVuex文件夹与store文件夹同级
然后,myVuex文件夹中创建index.js, 由于需要支持Vue.use和new myVuex.Store方法,(Vue.use需要用到install,后面会介绍;)所以暴露的Vuex需要如下内容:
index.js:
let Vuex = {
install: install,
Store: store,
version: '3.1.3'
}
export default Vuex
接下来我们先实现Vue.use(myVuex),我们先分析一下Vue.use具体做了什么操作,源码如下:
最主要就是调用了插件的install方法或自身。
export function initUse(Vue: GlobalAPI) {
Vue.use = function (plugin: Function | Object) {
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
const args = toArray(arguments, 1)
args.unshift(this)
// 调用install方法或自身
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
installedPlugins.push(plugin)
return this
}
}
所以,我们myVuex中需要增加install方法,如下:
var install = function install(Vue) {
console.log(Vue)
console.log(this) // 此處this是Vuex
// 需判断是否存在Vue
applyMixin(Vue)
}
function applyMixin(Vue) {
// 将vuexInit方法混淆到beforeCreate中,因此每个.vue页面创建的时候都会去调用vuexInit
// 所以每个页面都可以使用this.$store进行访问
Vue.mixin({ beforeCreate: vuexInit });
}
// 实现this.$store的使用
function vuexInit() {
console.log(this) // 此處this是Vue
var options = this.$options;
if (options.store) { // 说明是根节点
this.$store = options.store
} else {
this.$store = options.parent.$store
}
}
接着我们讲解store,新建store.js文件,专门处理store内容:
var Store = function Store(options) {
console.log(this) // Store本身
let keys = Object.keys(options);
for (let item of keys) {
this[item] = options[item]
}
}
// prototype属性指向构造函数创建的实例的原型对象,即Store.prototype === new Store().__proto__
Store.prototype.commit = function commit(type, payload) {
this.mutations[type].call(this, this.state, payload)
}
Store.prototype.dispatch = function dispatch(type, payload) {
this.actions[type].call(this, this.state, payload)
}
export default Store;
未解决问题:
store的数据双向绑定, 后续完善。
网友评论