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({
  renderh= > 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: {
    count10,},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.