用过vue开发的同学 肯定避免不了接触vuex 当我们使用vuex的时候 有没有想过 他内部的实现过程呢
首先他和我们的vue-router差不多 都是一个插件 所以 可以联想到 上次说的 有着公共代码
其次 也有不同点 使用的时候 new Vuex.Store({}) 所以 暴露出来的应该是store和install方法
下面以一个demo为例吧
<template>
<div>
<h1>测试啊</h1>
<div>count的值:{{$store.state.count}}</div>
<div @click="$store.commit('add')">commit</div>
<div @click="$store.dispatch('add')">dispatch</div>
<div>{{$store.getters.multiplyNum}}</div>
</div>
</template>
<script>
export default {
name: ''
}
</script>
<style lang='scss' scoped>
</style>
import Vue from 'vue'
// import Vuex from 'vuex'
import Vuex from './myStore'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:1
},
mutations: {
add(state){
state.count++
}
},
actions: {
add({commit}){
commit('add')
}
},
getters: {
multiplyNum(state){
return state.count*2
}
}
})
let Vue
class Store{
constructor(options){
this._mutations = options.mutations
this._actions = options.actions
this._wrappedGetters = options.getters
this.commit = this.commit.bind(this)
this.dispatch = this.dispatch.bind(this)
const computed = {}
this.getters = {}
const store = this
Object.keys(this._wrappedGetters).forEach(key=>{
const fn = store._wrappedGetters[key]
computed[key] = function(){
return fn(store.state)
}
Object.defineProperty(store.getters,key,{
get:()=>store._vm[key]
})
})
// this.state = new Vue({
// data:options.state
// })
//vue的隐式
this._vm = new Vue({
data:{
$$state:options.state
},
computed
})
}
//vue的隐式
get state(){
return this._vm._data.$$state
}
commit(type,state){
const entry = this._mutations[type]
if(!entry){
console.log("unknow")
}
entry(this.state,state)
}
dispatch(type,state){
const entry = this._actions[type]
if(!entry){
console.log("unknow")
}
entry(this,state)
}
}
function install(_Vue){
Vue=_Vue
Vue.mixin({
beforeCreate() {
if(this.$options.store){
Vue.prototype.$store = this.$options.store
}
},
})
}
export default {Store,install}
getters实际上就是computed 但因为computed是无参数状态 所以 执行的时候 封装了高阶函数 巧妙的避归了这个问题