Vuex
Vuex 集中式存储管理应⽤的所有组件的状态,并以相应的规则保证状态以可预测的⽅式发⽣变化。
数据流向图
核心概念(更多资料异步vue官网)
- state 状态、数据
- mutations 更改状态的函数
- actions 异步操作
- store 包含以上概念的容器
状态 - state
state保存应⽤状态
export default new Vuex.Store({
state: { counter:0 },
})
状态变更 - mutations
mutations⽤于修改状态
export default new Vuex.Store({
mutations: {
add(state) {
state.counter++
}
}
})
派⽣状态 - getters
从state派⽣出新状态,类似计算属性
export default new Vuex.Store({
getters: {
doubleCounter(state) { // 计算剩余数量
return state.counter * 2;
}
}
})
动作 - actions
添加业务逻辑,类似于controller
export default new Vuex.Store({
actions: {
add({ commit }) {
setTimeout(() => {
commit('add')
}, 1000)
}
}
})
实现一个简版的vuex
任务分析
- 实现插件
- 实现Store类
- 维持一个响应式状态state
- 实现commit()
- 实现dispatch()
- getters
- 挂载#store
- 实现Store类
初始化:Store声明、install实现
let Vue;
class Store {
constructor (options = {}) {
this._vm = new Vue ({
data: {
$$state: options.state
}
})
}
get state () {
return this._vm._data.$$state
}
set state () {
console.error('please use replaceState to reset state')
}
}
function install (_Vue) {
Vue = _vue
Vue.mixin ({
beforeCreate () {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store
}
}
})
}
export default { Store, install }
实现commit:根据用户传入type获取并执行对应mutation
class Store {
constructor (options = {}) {
// 保存用户配置的mutations选项
this._mutations = options.mutations || {}
}
commit (type, payload) {
// 获取type对应的mutation
const entry = this._mutations[type]
if (!entry) {
console.error(`unknown mutation type: ${type}`)
return
}
// 指定上下文为Store实例
// 传递state给mutation
entry(this.state, payload)
}
}
实现actions:根据用户传入type获取并执行对应action
class Store {
constructor (options = {}) {
// 保存用户编写的actions选项
this._actions = options.actions || {}
// 绑定commit上下文否则action中调用commit时可能出问题!!
// 同时也把action绑了,因为action可以互调
const store = this
const { commit, action } = store
this.commit = function boundCommit(type, payload) {
commit.call(store, type, payload)
}
this.action = function boundAction(type, payload) {
return action.call(store, type, payload)
}
}
dispatch (type, payload) {
// 获取用户编写的type对应的action
const entry = this._actions[type]
if (!entry) {
console.error(`unknown action type:${type}`)
return
}
// 异步结果处理常常需要返回Promise
return entry(this, payload)
}
}
实现getters:
class Store {
constructor (options = {}) {
// 保存用户配置的getters选项
this._wrappedGetters = options.getters || {}
// 定义computed选项
const computed = {}
this.getters = {}
const store = this
Object.keys(this._wrappedGetters).forEach(key => {
// 获取用户定义的getter
const fn = store._wrappedGetters[key]
// 转换为computed可以使用无参数形式
computed[key] = function () {
return fn(store.state)
}
// 为getters定义只读属性
Object.defineProperty(store.getters, key, {
get: () => store._vm[key]
})
})
this._vm = new Vue ({
data: {
$$state: options.state
},
computed: {
}
})
}
}
简版vuex全部代码
let Vue;
class Store {
constructor(options) {
this._mutations = options.mutations
this._actions = options.actions
this.commit = this.commit.bind(this)
this.dispatch = this.dispatch.bind(this)
// 保存用户配置的getters选项
this._wrappedGetters = options.getters || {}
// 定义computed选项
const computed = {}
this.getters = {}
const store = this
Object.keys(this._wrappedGetters).forEach(key => {
// 获取用户定义的getter
const fn = store._wrappedGetters[key]
// 转换为computed可以使用无参数形式
computed[key] = function () {
return fn(store.state)
}
// 为getters定义只读属性
Object.defineProperty(store.getters, key, {
get: () => store._vm[key]
})
})
// data响应式处理
// this.$store.state.xx
this._vm = new Vue({
data: {
$$state: options.state
},
computed
})
}
get state() {
return this._vm._data.$$state
}
set state(v) {
console.error('please use replaceState to reset state');
}
commit(type, payload) {
const entry = this._mutations[type]
if (!entry) {
console.error('unkown mutation type');
}
entry(this.state, payload)
}
dispatch(type, payload) {
const entry = this._actions[type]
if (!entry) {
console.error('unkown action type');
}
entry(this, payload)
}
}
// Vue.use
// install.apply(this, [this,...])
function install(_Vue) {
Vue = _Vue
Vue.mixin({
beforeCreate() {
if (this.$options.store) {
Vue.prototype.$store = this.$options.store
}
}
})
}
export default { Store, install };
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!