【vuex源码实现】03.手写实现一个响应state的getter
文章首发: https://shudong.wang/10386.html
源码:https://github.com/wsdo/vuex-...
实现getter
当我们想实现getter的时候,先了解他的作用
Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。
就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
实现思路
说白了,getter 就是把 state 经过一些逻辑过虑一下返回一个新的 state
这个逻辑 无非就是一个功能函数,so,我们应该实现一个函数,根据 state变化而变化
这时候,响应式数据的功劳 Object.defineProperty
首先我们来什么一个函数
接收参数
状态:因为我们要基于一个状态来处理返回一个状态所以需要一个状态
getter名字:我们在一个状态管理里面会有多个getter,所以会有getter名字,来区分
函数:因为我们要使用一个函数来处理一个逻辑,所以需要接收一个函数
函数如下
registerGetter(status,name,fn)
我们需要监听state状态,然后做出响应
const registerGetter = (store, fn, name) => { Object.defineProperty(store.getters, name, { get: () => { return fn(store.state) }, }) }
初始化的时候,需要让我们所有的,getter函数执行
const forEachValue = (obj, fn) => Object.keys(obj).forEach(key => fn(obj[key], key))
下面是实现getter的全部代码 可以慢慢试着去理解分析
参考仓库:
main.js
import Vue from 'vue' import App from './App.vue' import stark from './store' Vue.config.productionTip = false new Vue({ render: h => h(App), stark, }).$mount('#app')
Stark.vue
created() { console.log('getters',this.$stark.getters); },
打印结果
store/index.js
import Vue from 'vue' import Vuex from '../store' Vue.use(Vuex) export default new Vuex.Store({ state: { count: 10, }, getters: { getNumOne(state) { return state.count + 5 }, }, })
store.js
import applyMixin from './mixin' import Vue from 'vue' const forEachValue = (obj, fn) => Object.keys(obj).forEach(key => fn(obj[key], key)) const registerGetter = (store, fn, name) => { Object.defineProperty(store.getters, name, { get: () => { return fn(store.state) }, }) } const resetStoreVM = (store, state) => { store._vm = new Vue({ data: { state: state, }, }) } export class Store { constructor(options = {}) { this.options = options this.getters = {} forEachValue(options.getters, (fn, name) => { registerGetter(this, fn, name) }) resetStoreVM(this, options.state) } get state() { return this.options.state } } export const install = Vue => { applyMixin(Vue) }
mixin.js
export default function(Vue) { Vue.mixin({ beforeCreate: starkInit }) function starkInit() { const options = this.$options if (options.stark) { this.$stark = typeof options.stark === 'function' ? options.stark() : options.stark } else if (options.parent && options.parent.$stark) { this.$stark = options.parent.$stark } } }
相关推荐
源码zanqunet 2020-10-28
anchongnanzi 2020-09-21
CRMCRMCRMDS 2020-08-12
Cricket 2020-07-27
瓜牛呱呱 2020-11-12
柳木木的IT 2020-11-04
yifouhu 2020-11-02
lei0 2020-11-02
源码zanqunet 2020-10-26
一叶梧桐 2020-10-14
码代码的陈同学 2020-10-14
lukezhong 2020-10-14
lzzyok 2020-10-10
clh0 2020-09-18
changcongying 2020-09-17
星辰大海的路上 2020-09-13
abfdada 2020-08-26
mzy000 2020-08-24
shenlanse 2020-08-18