Today we are going to talk about why some states in VUEX need to be packaged using computed, while others can be used directly in data

The problem to show

<body>
    <div id="app">
      <div>{{count}}</div>
      <div>{{d.count}}</div>
      <div>{{$options.render}}</div>
      <button @click="addCount">Click on the add</button>
    </div>
</body>

Copy the code
    Vue.use(Vuex);

    const state = {
      count: 1};const mutations = {
      addCount(state) {
        console.log("mutation"); state.count++; }};const actions = {
      addCount({ commit, state }) {
        console.log("action");
        commit("addCount"); }};const store = new Vuex.Store({
      state,
      mutations,
      actions,
      /** trict: true*/
    });
    new Vue({
      el: "#app",
      store,
      data() {
        return { count: this.$store.state.count, d: this.$store.state };
      },
      methods: {
        addCount() {
          // this.d.count++;
          this.$store.state.count++; // If strict mode is not enabled, no error will be reported
          // this.$store.dispatch("addCount");,}}});Copy the code

So from the code above when I click the button the addCount method gets called from updating the value of count in state, what’s going to be on the page? One 2 or two 2’s. The answer is that the

{{count}}

tag on the first line will display 1, while the

{{d.c. ount}}

tag on the second line will display 2.

Why does this happen? So what I’m going to do here is I’m going to show you how to initialize the entire page depending on the initialization process.

Depends on the initialization process

We know that vue initializes initLifecycle, initEvents… InitState and so on. InitState initializes initProps, initMethods, initData, and so on. Let’s focus on the initData method

function initData (vm: Component) {
  let data = vm.$options.data
  // can be taken as the first value here
  data = vm._data = typeof data === 'function'
    ? getData(data, vm)
    : data || {}
   
   / /... Omit some code
   
  // Objects hijack core methods
  observe(data, true /* asRootData */)}// The following is a state-responsive implementation of VUEX
store._vm = new Vue({ data: { ?state: state }, computed })
Copy the code

The responsive implementation of VUex directly uses the responsive mechanism of Vue. When new vuex.store (), state has been set in a responsive manner. At this time, all properties of state in the SUBs attribute of Dep object are empty Array subS: Array

; = []. This means that there are no observer functions in state that can be fired at this point.

Vue({el:’#app’}) {count: 1, d: This.$store.state}, this.$store.state.count will trigger two get functions: state and state.count. However, the component does not mount render at this point, so the two get functions do not collect the component’s Watcher render observer, because dep. target is undefined at this point. So count is going to be assigned 1, and then d is going to refer to the memory of state so D is going to be assigned a reference to state

Immediately after $mount the render observer watcher is created, it is assigned to dep. target and the render function is called. Function anonymous(){with(this){return _c(‘div’,{attrs:{“id”:”app”}},[_c(‘div’,[_v(_s(count))]),_v(” “),_c(‘div’,[_v(_s(d.count))]),_v(” “), _c (‘ div ‘, [_v (_s ($options. Render))]), _v (” “), _c (‘ button ‘{on: {” click “: addCount}}, [_v (” click increase”)])]}}, When this method is executed, count and D.C. ount are evaluated. Count will collect the current render dependency d will collect, what about D.C. ount? It refers to state.count so the value triggers a dependency collection of state and state.count that enrolls the render viewer in their respective DEP. So that explains why one responds and one doesn’t, right

The Computed response type

Some of you are wondering why DID I write it so he can respond?

new Vue({
      el: "#app",
      store,
      data() {
        return {  d: this.$store.state };
      },
      computed: {
        count() {
            return this.$store.state.count; }}methods: {
        addCount() {
          console.log("addCount");
          // this.d.count++;
          this.$store.state.count++;
          console.log(this.$store.state.count);
          // this.$store.dispatch("addCount");,}}});Copy the code

This.$store.state.count is a basic data type, so it becomes a constant value at initDate. Therefore, you need to create a watcher using computed data and trigger the collection of rendered Watcher into the DEP of this.$store.state.count. This will trigger the calculation property Watcher to set dirty = true, and then trigger render Watcher to get the latest value and finish rendering

What is dependency collection

To be continued…