vuex的用法
完整vuex内传入对象 一般需要 state、mutation、actions
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex) // 插件引用
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
add(state) {
// state从哪来
state.count++
}
},
actions: {
// 上下文对象是什么,从哪来
add({commit}) {
setTimeout(() => {
commit('add')
}, 1000);
}
},
modules: {
}
})
实现注意点:
1、mutation的方法实现传入需要state
2、action 传入需要 { commit }
3、action 使用时需要dispatch触发
在页面上的使用
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/404">404</router-link>
</div>
<div>
data:
{{$store.state}}
</div>
<div>
全局状态:
<p @click="$store.commit('add')">{{$store.state.count}}</p>
</div>
<div>
<p @click="$store.dispatch('add')">{{$store.state.count}}</p>
</div>
<p>{{$store.getters.doubleCounter}}</p>
<p>{{$store.cpGetters.doubleCounter}}</p>
<router-view />
</div>
</template>
使用分析:
1、$store 在 beforeCreate 的时候把 store 挂上 this 上
2、$store.commit 执行 mutation 的操作
3、$store.dispatch 执行 action 上的操作
4、$store.getters 类似 computed 的操作
具体实现
实现store类的架构预演
步骤:
- 维持一个响应式状态state
- 实现commit
- 实现dispatch
- getters
- 挂载store
1、实现store
let Vue // 通过install传入
class Store {
// 构造器
constructor({ state, mutations, actions, getters }) {
// 很明显要给state内的值作响应式
// 这样才能做视图更新
}
// commit 传入 mutation定义的方法key值、以及进行处理的值
commit(type, payload) {}
// dispatch 传入 action定义的方法key值、以及进行处理的值
dispatch(type, payload) {}
}
// 处理 install 可以让Vue.install 方法
function install(_vue) {
Vue = _vue
// 延迟挂载store
Vue.mixin({
beforeCreate() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store
}
}
})
}
export default {
Store,
install
}
// 这里导出对象区别于 router
// 因为平常使用 vuex的时候 是 new Vuex.Store({})
// 而router的使用是直接 new Router({})
2、具体实现
class Store {
constructor({ state, mutations, actions, getters }) {
// 1.保存选项
this._state = state
this._mutations = mutations || {}
this._actions = actions || {}
// 内部方法绑定this
this.commit = this.commit.bind(this)
this.dispatch = this.dispatch.bind(this)
const computed = {}
for (let key in getters) {
const fn = getters[key]
computed[key] = () => {
return fn(this.state)
}
}
// 2.做响应式state属性
this._vm = new Vue({
data: function() {
return { $$state: state }
},
computed
})
// 3.getters
// 动态设置getters属性 还有 响应式
// 附加能否利用上vue的compute属性
console.log('getters实现')
const _getters = {}
for (let key in getters) {
const innerState = this.state // 内部获取不到this
// const item = getters[key]
Object.defineProperty(_getters, key, {
get: function() {
return getters[key](innerState)
},
enumerable: true
})
}
this.getters = _getters
}
get state() { // 利用data实现, return _vm.$$state 也可
//_data 响应对象 $data原始对象
return this._vm._data.$$state
}
set state(v) {
console.log("error can't set val")
}
get cpGetters() { // 利用vue computed实现
return this._vm
}
commit(type, payload) {
// 获取mutations
const entry = this._mutations[type]
if (!entry) {
console.log('获取不到mutations')
return
}
entry(this.state, payload)
}
dispatch(type, payload) {
const entry = this._actions[type]
if (!entry) {
console.log('获取不到actions')
return
}
// commit 和 dispatch 绑过this 所以可以使用
entry(this, payload)
}
}