我同时使用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组件?


当前回答

====== store ===== import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex) export default new Vuex.Store({ state: { showRegisterLoginPage: true, user: null, allitem: null, productShow: null, userCart: null }, mutations: { SET_USERS(state, payload) { state.user = payload }, HIDE_LOGIN(state) { state.showRegisterLoginPage = false }, SHOW_LOGIN(state) { state.showRegisterLoginPage = true }, SET_ALLITEM(state, payload) { state.allitem = payload }, SET_PRODUCTSHOW(state, payload) { state.productShow = payload }, SET_USERCART(state, payload) { state.userCart = payload } }, actions: { getUserLogin({ commit }) { axios({ method: 'get', url: 'http://localhost:3000/users', headers: { token: localStorage.getItem('token') } }) .then(({ data }) => { // console.log(data) commit('SET_USERS', data) }) .catch(err => { console.log(err) }) }, addItem({ dispatch }, payload) { let formData = new FormData() formData.append('name', payload.name) formData.append('file', payload.file) formData.append('category', payload.category) formData.append('price', payload.price) formData.append('stock', payload.stock) formData.append('description', payload.description) axios({ method: 'post', url: 'http://localhost:3000/products', data: formData, headers: { token: localStorage.getItem('token') } }) .then(({ data }) => { // console.log('data hasbeen created ', data) dispatch('getAllItem') }) .catch(err => { console.log(err) }) }, getAllItem({ commit }) { axios({ method: 'get', url: 'http://localhost:3000/products' }) .then(({ data }) => { // console.log(data) commit('SET_ALLITEM', data) }) .catch(err => { console.log(err) }) }, addUserCart({ dispatch }, { payload, productId }) { let newCart = { count: payload } // console.log('ini dari store nya', productId) axios({ method: 'post', url: `http://localhost:3000/transactions/${productId}`, data: newCart, headers: { token: localStorage.getItem('token') } }) .then(({ data }) => { dispatch('getUserCart') // console.log('cart hasbeen added ', data) }) .catch(err => { console.log(err) }) }, getUserCart({ commit }) { axios({ method: 'get', url: 'http://localhost:3000/transactions/user', headers: { token: localStorage.getItem('token') } }) .then(({ data }) => { // console.log(data) commit('SET_USERCART', data) }) .catch(err => { console.log(err) }) }, cartCheckout({ commit, dispatch }, transactionId) { let count = null axios({ method: 'post', url: `http://localhost:3000/transactions/checkout/${transactionId}`, headers: { token: localStorage.getItem('token') }, data: { sesuatu: 'sesuatu' } }) .then(({ data }) => { count = data.count console.log(count, data) dispatch('getUserCart') }) .catch(err => { console.log(err) }) }, deleteTransactions({ dispatch }, transactionId) { axios({ method: 'delete', url: `http://localhost:3000/transactions/${transactionId}`, headers: { token: localStorage.getItem('token') } }) .then(({ data }) => { console.log('success delete') dispatch('getUserCart') }) .catch(err => { console.log(err) }) } }, modules: {} })

其他回答

您可以使用Vuex操作、getter、计算属性和监视器的组合来侦听Vuex状态值的变化。

HTML代码:

<div id="app" :style='style'>
  <input v-model='computedColor' type="text" placeholder='Background Color'>
</div>

JavaScript代码:

'use strict'

Vue.use(Vuex)

const { mapGetters, mapActions, Store } = Vuex

new Vue({
    el: '#app',
  store: new Store({
    state: {
      color: 'red'
    },
    getters: {
      color({color}) {
        return color
      }
    },
    mutations: {
      setColor(state, payload) {
        state.color = payload
      }
    },
    actions: {
      setColor({commit}, payload) {
        commit('setColor', payload)
      }
    }
  }),
  methods: {
    ...mapGetters([
        'color'
    ]),
    ...mapActions([
        'setColor'
    ])
  },
  computed: {
    computedColor: {
        set(value) {
        this.setColor(value)
      },
      get() {
        return this.color()
      }
    },
    style() {
        return `background-color: ${this.computedColor};`
    }
  },
  watch: {
    computedColor() {
        console.log(`Watcher in use @${new Date().getTime()}`)
    }
  }
})

参见JSFiddle演示。

如上所述,直接在商店中观察变化并不是一个好主意

但在一些非常罕见的情况下,它可能对某人有用,所以我将留下这个答案。其他情况请参见@gabriel-robert answer

你可以通过州政府,$watch。将此添加到组件中创建的(或需要执行此方法的地方)方法中

this.$store.watch(
    function (state) {
        return state.my_state;
    },
    function () {
        //do something on data change
    },
    {
        deep: true //add this if u need to watch object properties change etc.
    }
);

详情:https://vuex.vuejs.org/api/#watch

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

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

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

理论

我发现,出于某种原因,对$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>

如果您只是想监视一个状态属性,然后根据该属性的变化在组件中进行相应的操作,请参阅下面的示例。

在store.js:

export const state = () => ({
 isClosed: false
})
export const mutations = {
 closeWindow(state, payload) {
  state.isClosed = payload
 }
}

在这个场景中,我创建了一个布尔状态属性,我将在应用程序的不同地方更改,如下所示:

this.$store.commit('closeWindow', true)

现在,如果我需要在其他组件中监视状态属性,然后更改本地属性,我会在挂载的钩子中写入以下内容:

mounted() {
 this.$store.watch(
  state => state.isClosed,
  (value) => {
   if (value) { this.localProperty = 'edit' }
  }
 )
}

首先,我在状态属性上设置了一个监视器,然后在回调函数中,我使用该属性的值来更改localProperty。

我希望这能有所帮助!