我同时使用vuex和vuejs 2。

我是vuex的新手,我想看一个商店变量的变化。

我想在我的vue组件中添加手表功能

这是我目前所拥有的:

import Vue from 'vue';
import {
  MY_STATE,
} from './../../mutation-types';

export default {
  [MY_STATE](state, token) {
    state.my_state = token;
  },
};

我想知道my_state是否有任何变化

我怎么看店。My_state在我的vuejs组件?


当前回答

其实很简单:

watch: {
  '$store.state.drawer': function() {
    console.log(this.$store.state.drawer)
  }
}

如果存储在一个模块中,使用:

'$store.state.myModule.drawer'

对于嵌套文件,使用:

'$store.state.fileOne.fileTwo.myModule.drawer'

其他回答

你不应该使用组件的监视器来监听状态的变化。我建议您使用getter函数,然后在组件中映射它们。

import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters({
      myState: 'getMyState'
    })
  }
}

在你的店里:

const getters = {
  getMyState: state => state.my_state
}

您应该能够通过使用此功能侦听对您的商店所做的任何更改。myState在你的组件。

https://vuex.vuejs.org/en/getters.html#the-mapgetters-helper

如果你使用typescript,那么你可以:

import {Watch} from "vue-property-decorator"; .. @Watch (" $ store.state.something”) private watchSomething() { //使用这个。$store.state。可以访问的东西 ... }

在组件内部,创建一个计算函数

computed:{
  myState:function(){
    return this.$store.state.my_state; // return the state value in `my_state`
  }
}

现在可以观察计算出的函数名,比如

watch:{
  myState:function(newVal,oldVal){
    // this function will trigger when ever the value of `my_state` changes
  }
}

在vuex状态my_state中所做的更改将反映在计算函数myState中,并触发手表函数。

如果状态my_state包含嵌套数据,则处理程序选项将提供更多帮助

watch:{
  myState:{
    handler:function(newVal,oldVal){
      // this function will trigger when ever the value of `my_state` changes
    },
    deep:true
  }
}

这将监视my_state存储中的所有嵌套值。

通过观察和设置值变化来创建存储变量的Local状态。 这样,表单输入v-model的局部变量更改不会直接改变存储变量。

data() {
  return {
    localState: null
  };
 },
 computed: {
  ...mapGetters({
    computedGlobalStateVariable: 'state/globalStateVariable'
  })
 },
 watch: {
  computedGlobalStateVariable: 'setLocalState'
 },
 methods: {
  setLocalState(value) {
   this.localState = Object.assign({}, value);
  }
 }

我想尽了一切办法让它运转起来。

理论

我发现,出于某种原因,对$store对象的更改不一定会触发.watch方法。我的解决办法是

Store Create a complex data set which should but doesn't propagate changes to a Component Create an incrementing counter in the state to act as a flag, which does propagate changes to a Component when watched Create a method in $store.mutators to alter the complex dataset and increment the counter flag Component Watch for changes in the $store.state flag. When change is detected, update locally relevant reactive changes from the $store.state complex data set Make changes to the $store.state's dataset using our $store.mutators method

实现

它的实现是这样的:

商店

let store = Vuex.Store({
  state: {
    counter: 0,
    data: { someKey: 0 }
  },
  mutations: {
    updateSomeKey(state, value) {
      update the state.data.someKey = value;
      state.counter++;
    }
  }
});

组件

  data: {
    dataFromStoreDataSomeKey: null,
    someLocalValue: 1
  },
  watch: {
    '$store.state.counter': {
        immediate: true,
        handler() {
           // update locally relevant data
           this.someLocalValue = this.$store.state.data.someKey;
        }
     }
  },
  methods: {
    updateSomeKeyInStore() { 
       this.$store.commit('updateSomeKey', someLocalValue);
  }

可运行演示

这很复杂,但基本上我们在这里观察一个要更改的标志,然后更新本地数据以反映存储在$状态中的对象的重要更改

Vue.config.devtools = false const store = new Vuex.Store({ state: { voteCounter: 0, // changes to objectData trigger a watch when keys are added, // but not when values are modified? votes: { 'people': 0, 'companies': 0, 'total': 0, }, }, mutations: { vote(state, position) { state.votes[position]++; state.voteCounter++; } }, }); app = new Vue({ el: '#app', store: store, data: { votesForPeople: null, votesForCompanies: null, pendingVote: null, }, computed: { totalVotes() { return this.votesForPeople + this.votesForCompanies }, peoplePercent() { if (this.totalVotes > 0) { return 100 * this.votesForPeople / this.totalVotes } else { return 0 } }, companiesPercent() { if (this.totalVotes > 0) { return 100 * this.votesForCompanies / this.totalVotes } else { return 0 } }, }, watch: { '$store.state.voteCounter': { immediate: true, handler() { // clone relevant data locally this.votesForPeople = this.$store.state.votes.people this.votesForCompanies = this.$store.state.votes.companies } } }, methods: { vote(event) { if (this.pendingVote) { this.$store.commit('vote', this.pendingVote) } } } }) <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script> <script src="https://unpkg.com/vuex@3.5.1/dist/vuex.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"> <div id="app"> <form @submit.prevent="vote($event)"> <div class="form-check"> <input class="form-check-input" type="radio" name="vote" id="voteCorps" value="companies" v-model="pendingVote" > <label class="form-check-label" for="voteCorps"> Equal rights for companies </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="vote" id="votePeople" value="people" v-model="pendingVote" > <label class="form-check-label" for="votePeople"> Equal rights for people </label> </div> <button class="btn btn-primary" :disabled="pendingVote==null" >Vote</button> </form> <div class="progress mt-2" v-if="totalVotes > 0" > <div class="progress-bar" role="progressbar" aria-valuemin="0" :style="'width: ' + peoplePercent + '%'" :aria-aluenow="votesForPeople" :aria-valuemax="totalVotes" >People</div> <div class="progress-bar bg-success" role="progressbar" aria-valuemin="0" :style="'width: ' + companiesPercent + '%'" :aria-valuenow="votesForCompanies" :aria-valuemax="totalVotes" >Companies</div> </div> </div>