programing

인수가 있는 Vuex 매핑 Getter - 캐시됨?

newsource 2022. 8. 18. 23:44

인수가 있는 Vuex 매핑 Getter - 캐시됨?

다음은 템플릿 내에서 사용하기 위해 Vue 인스턴스에 매핑해야 하는 매개 변수화된 getter가 있는 Vuex Store의 예입니다.

const store = new Vuex.Store({
  state: {
    lower: 5,
    higher: 10,
    unrelated: 3
  },
  getters: {
    inRange: state => value => {
      console.log('inRange run')
      return (state.lower <= value) && (state.higher >= value)
    }
  },
  mutations: {
    reduceLower: state => state.lower--,
    incrementUnrelated: state => state.unrelated++
  }
})

new Vue({
  el: '#app',
  template: "<div>{{ inRange(4) }}, {{ unrelated }}</div>",
  store,
  computed: Object.assign(
    Vuex.mapGetters(['inRange']),
    Vuex.mapState(['unrelated'])
  ),
})

setTimeout(function() {
  console.log('reduceLower')
  store.commit('reduceLower')
  setTimeout(function() {
    console.log('incrementUnrelated')
    store.commit('incrementUnrelated')
  }, 3000);  
}, 3000);
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex/dist/vuex.js"></script>
<div id="app"></div>

우선, 이것은 유효한 동작 코드인 것 같습니다.computed계산 속성의 캐시 세트입니다.이 시나리오의 동작이 궁금한데 캐싱이 진행 중입니까?그렇지 않은 경우 고려해야 할 성능 문제가 있습니까?로 인해 변화하지는 , 이 상태가 변화하지는 않습니다.method

이게 안티 패턴인가요?이 예는 실제는 아니지만, 저는 이 스토어의 논리를 일원화하고 싶습니다.

갱신하다

가 되는 했습니다.lower/higher 의거한 값inRangegetter는 기반이며 Vue 인스턴스에 대해 실제로 반응합니다(상태로 매핑되지 않음). ,, 개, 개, 개, 개, 개, 개, 개, 개, 개, 개, 개, 개unrelated이 값은 계산의 일부가 아닙니다.매핑된 getter가 캐시된 경우 관련되지 않은 값을 변경해도 getter가 다시 호출되지 않습니다.단, getter는 다시 호출됩니다.

제 결론은 캐싱이 없기 때문에 기존의 계산 속성보다 성능이 떨어지지만 기능적으로는 여전히 정확하다는 것입니다.

이 패턴에 결함이 있는지, 아니면 더 나은 성능을 제공하는지에 대한 질문은 여전히 열려 있습니다.

내 생각에 이건 안티 패턴이야.이치노캐싱은 .inRange 함수)을state 의존성을 Vue는 0개의 반응 의존성을 검출합니다.

Getters는 이러한 방식으로 매개 변수를 지정할 수 없습니다. 상태에 기반을 둔 것만 도출할 수 있습니다.따라서 범위를 스테이트로 저장할 수 있으면 동작합니다(캐시됩니다).

유사한 질문: vuexjs getter with 인수

이 동작을 일원화하고 싶기 때문에 다른 모듈(아마 믹스인)로 하는 것이 좋다고 생각합니다..computed하다.

다음과 같은 경우:

import { inRange } from './state/methods';
import { mapGetters }  from 'vuex';

const Example = Vue.extend({
  data: {
    rangeInput: 10
  },
  computed: {
    ...mapGetters(['lower', 'higher']),
    inRange() {
      return inRange(this.rangeInput, this.lower, this.higher);
    }
  }
});

Matt의 답변을 받아들인 이유를 설명하기 위해 작업 스니펫을 소개합니다.주의할 점은 다음과 같습니다.

Vuex.mapGetters(['inRange'])

실제 계산 속성이 있습니다.

inRange4: function() {
  return this.$store.getters.inRange(4);
}

이로 인해 스니펫을 실행하면 알 수 있듯이 값이 올바르게 캐시됩니다.앞에서 설명한 바와 같이 이 패턴은 계산속성(inRange1, inRange2, inRange3 등)이 너무 많기 때문에 사용할 수 있는 패턴은 아니지만 문제의 예와 함께 질문에 답합니다.

질문의 코드를 변경하지 않고 계속 사용하기로 했습니다.

주의: Matt의 답변은 이 코드와 정확히 일치하지 않으며, 그의 의도는 스토어의 상태를 Vue 인스턴스에 매핑하는 것이었다고 생각합니다.이것은 불필요하다고 생각합니다.

const store = new Vuex.Store({
  state: {
    lower: 5,
    higher: 10,
    unrelated: 3
  },
  getters: {
    inRange: state => value => {
      console.log('inRange run')
      return (state.lower <= value) && (state.higher >= value)
    }
  },
  mutations: {
    reduceLower: state => state.lower--,
    incrementUnrelated: state => state.unrelated++
  }
})

new Vue({
  el: '#app',
  template: "<div>{{ inRange4 }}, {{ unrelated }}</div>",
  store,
  computed: Object.assign(
    {
      inRange4: function() {
        return this.$store.getters.inRange(4);
      }
    },
    Vuex.mapState(['unrelated'])
  ),
})

setTimeout(function() {
  console.log('reduceLower')
  store.commit('reduceLower')
  setTimeout(function() {
    console.log('incrementUnrelated')
    store.commit('incrementUnrelated')
  }, 3000);  
}, 3000);
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex/dist/vuex.js"></script>
<div id="app"></div>

이 문제를 해결하는 방법이 있는 것 같습니다. 계산된 값으로 지도를 만들고 다음과 같이 액세스합니다.

inrange[4];

다양한 종류의 접근자를 초기화하기 위해 자주 사용합니다.백엔드에서 어레이를 가져와 특정 필드(ID 등)에서 액세스해야 합니다.위의 예에서는 범위가 작기 때문에 타당하다고 생각됩니다.

const store = new Vuex.Store({
  state: {
    lower: 5,
    higher: 10,
    unrelated: 3
  },
  getters: {
    inRange: state => {
      console.log('inRange run')
      var result = {};
      for( var i = state.lower; i < state.higher; i++) {
        result[i] = true;
      }
      return result;
    }
  },
  mutations: {
    reduceLower: state => state.lower--,
    incrementUnrelated: state => state.unrelated++
  }
})

new Vue({
  el: '#app',
  template: "<div>{{ inRange[4] }}, {{ unrelated }}</div>",
  store,
  computed: Object.assign(
    {
      inRange: function() {
        return this.$store.getters.inRange;
      }
    },
    Vuex.mapState(['unrelated'])
  ),
})

setTimeout(function() {
  console.log('reduceLower')
  store.commit('reduceLower')
  setTimeout(function() {
    console.log('incrementUnrelated')
    store.commit('incrementUnrelated')
  }, 3000);  
}, 3000);
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex/dist/vuex.js"></script>
<div id="app"></div>

언급URL : https://stackoverflow.com/questions/44575886/vuex-mapping-getter-with-argument-cached