vuex
核⼼概念
- state 状态、数据
- mutations 更改状态的函数
- actions 异步操作
- store 包含以上概念的容器
测试用例
store/index.js
import Vue from 'vue'
import Vuex from './my-vuex.js'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
counter: 1
},
mutations: {
add(state) {
state.counter++
}
},
actions: {
add({ commit }) {
setTimeout(() => {
commit('add')
}, 1000)
}
},
getters: {
doubleCounter(state) {
return state.counter * 2
}
}
)}
<p @click="$store.commit('add')">counter: {{$store.state.counter}}</p>
<p @click="$store.dispatch('add')">async counter: {{$store.state.counter}}</p>
<p>double:{{$store.getters.doubleCounter}}</p>
任务分析
- 实现插件
- 实现Store类
- 维持⼀个响应式状态state
- 实现commit()
- 实现dispatch()
- getters
- 挂载$store
初始化:Store声明、install实现,my-vuex.js:
let Vue
class Store {
constructor(options = {}) {
this._vm = new Vue({
data: {
$$state: options.state
}
})
}
get state() {
return this._vm._data.$$state
}
set state(v) {
// console.error('please use replaceState to reset state')
return
}
}
function install(_Vue) {
Vue = _Vue
Vue.mixin({
beforeCreate() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store
}
}
})
}
export default {
Store,
install
}
export default { Vuex, install }
实现commit:根据⽤户传⼊type获取并执⾏对应mutation
class Store {
constructor(options = {}) {
this._mutation = options.mutations || {}
this.commit = this.commit.bind(this)
}
coommit(type, payload) {
const mutation = this._mutations[type]
if (!mutation) {
// console.error(`unknown mutation type: ${type}`)
return
}
mutation(this.state, payload)
}
}
实现actions:根据⽤户传⼊type获取并执⾏对应action
class Store {
constructor(options = {}) {
this._actions = options.actions || {}
this.dispatch = this.dispatch.bind(this)
}
dispatch(type, payload) {
const action = this._actions[type]
if (!action) {
// console.error(`unknown action type: ${type}`)
return
}
action(this, payload)
}
}
//
class Vuex {
constructor(options = {}) {
this._actions = options.actions || {}
this.dispatch = this.dipatch.bind(this)
}
dispatch(type, payload) {
const action = this._actions[type]
if (!action) {
console.error(`unknown action type: ${type}`)
return
}
action(this, payload)
}
}
实现getters
class Store {
constructor(options = {}) {
this._wrapperGetters = options.getters || {}
this.getters = {}
const computed = {}
const store = this
// computed 属性中函数不带参数,封装一层
Object.keys(store._wrapperGetters).forEach(key => {
const fn = store._wrapperGetters[key]
computed[key] = function () {
return fn(store.state)
}
Object.defineProperty(store.getters, key, {
get: () => {
// computed中执行
return store._vm[key]
}
})
})
this._vm = new Vue({
data: {
$$state: options.state
},
computed
})
}
}