Source code address: github.com/wsdo/vuex-a…
Implement the getter
Vuex allows us to define “getters” in stores (think of them as computed properties of stores). Just like evaluating properties, the return value of a getter is cached based on its dependency and is recalculated only if its dependency value changes.
Implementation approach
So basically, a getter is a way of taking the state and going through some logic and returning a new state and that logic is nothing more than a function function, so, we should implement a function that changes depending on the state and at that point, Credit for responsive data object.defineProperty
First of all, what is the function
Receive parameters
State: because we need to return a state based on a state, we need a state getter name: we have multiple getters in a state manager, so we have getter names to distinguish between functions: because we need to use a function to process a logic, we need to receive a function
Function as follows
RegisterGetter (status, name, fn)Copy the code
We need to listen for state and then respond
const registerGetter = (store, fn, name) = > {
Object.defineProperty(store.getters, name, {
get: () = > {
return fn(store.state)
},
})
}
Copy the code
When we initialize, we need to get all of our getters to execute
const forEachValue = (obj, fn) = > Object.keys(obj).forEach(key= > fn(obj[key], key))
Copy the code
Here’s all the code to implement the getter so you can try to understand the analysis slowly
Reference warehouse:
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')
Copy the code
Stark.vue
created() {
console.log('getters'.this.$stark.getters);
},
Copy the code
Print the result
The 2019-07-25-2019-07-25
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}},})Copy the code
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)
}
Copy the code
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
}
}
}
Copy the code
Recently the interview occasionally asked how vuex getter is implemented, few people will answer the core point, I hope this article can help you.