Programing

vuex에서 스토어 값을 보는 방법?

c10106 2022. 4. 3. 19:40
반응형

vuex에서 스토어 값을 보는 방법?

나는 사용하고 있다vuex그리고vuejs 2함께

나는 이 생소하다.vuex, 나는 보고싶다 astore가변적 변화

나는 더하고 싶다.watch나의 기능을 하다.vue component

지금까지 내가 가지고 있는 것은 다음과 같다.

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

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

앞으로 어떤 변화가 있는지 알고 싶다.my_state

어떻게 보는가store.my_state내 Vuejs 컴포넌트에?

예를 들어 과일 바구니가 있다고 하자, 그리고 바구니에서 과일을 추가하거나 제거할 때마다 (1) 과일 수치에 대한 정보를 표시하려고 하지만, (2) 과일 수를 어떤 화려한 방법으로 알려주고 싶어한다고 하자...

과수 성분 성분부에를 하다

<template>
  <!-- We meet our first objective (1) by simply -->
  <!-- binding to the count property. -->
  <p>Fruits: {{ count }}</p>
</template>

<script>
import basket from '../resources/fruit-basket'

export default () {
  computed: {
    count () {
      return basket.state.fruits.length
      // Or return basket.getters.fruitsCount
      // (depends on your design decisions).
    }
  },
  watch: {
    count (newCount, oldCount) {
      // Our fancy notification (2).
      console.log(`We have ${newCount} fruits now, yay!`)
    }
  }
}
</script>

참고: 의 함수 이름watch객체, 에 있는 함수의 이름과 일치해야 함computed이의를 제기하다위의 예에서 이름은count.

감시 대상 속성의 새 값과 이전 값은 파라미터로 감시 콜백(카운트 함수)에 전달된다.

바구니 가게는 다음과 같이 보일 수 있다.

과일 맛이 나는.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const basket = new Vuex.Store({
  state: {
    fruits: []
  },
  getters: {
    fruitsCount (state) {
      return state.fruits.length
    }
  }
  // Obviously you would need some mutations and actions,
  // but to make example cleaner I'll skip this part.
})

export default basket

다음 리소스에서 자세히 알아보십시오.

다음과 같이 간단하다.

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

국가 변화를 듣기 위해 컴포넌트의 감시자를 이용해서는 안 된다.게터 기능을 사용한 다음 구성 요소 내부에 매핑하십시오.

import { mapGetters } from 'vuex'

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

스토어에서:

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

당신은 당신의 상점에 대한 모든 변경사항을 들을 수 있어야 한다.this.myState당신의 구성 요소 안에.

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

위에서 언급한 바와 같이 매장에서 직접 변화를 지켜보는 것은 좋지 않다.

그러나 아주 드문 경우에 그것은 누군가에게 유용할 수 있기 때문에 나는 이 대답을 남길 것이다.다른 경우에는 @gabriel-robert 답변을 참조하십시오.

당신은 이것을 끝까지 할 수 있다.state.$watch. 이것을 당신의 것에 추가하라.created구성 요소에서 (또는 이 방법을 실행해야 하는 경우) 방법

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

물어보는 사람이 Vuex와 함께 시계를 사용하길 원하는 것 같아.

this.$store.watch(
      (state)=>{
        return this.$store.getters.your_getter
      },
      (val)=>{
       //something changed do something

      },
      {
        deep:true
      }
      );

이는 Getter와 함께 문제를 해결할 수 없고 실제로 감시자가 필요한 모든 사람들을 위한 것이다. 예를 들어, 비 Vue 타사 자료와 대화할 수 있는 감시자가 필요하다(Watchers 사용 시점은 Vue Watchers 참조).

Vue 구성 요소의 감시자와 계산된 값도 계산된 값에 대해 작용한다.따라서 vuex와 다를 바 없다.

import { mapState } from 'vuex';

export default {
    computed: {
        ...mapState(['somestate']),
        someComputedLocalState() {
            // is triggered whenever the store state changes
            return this.somestate + ' works too';
        }
    },
    watch: {
        somestate(val, oldVal) {
            // is triggered whenever the store state changes
            console.log('do stuff', val, oldVal);
        }
    }
}

로컬 상태와 글로벌 상태를 결합하는 것만이 문제라면 mapState의 문서도 예를 제공한다.

computed: {
    ...mapState({
        // to access local state with `this`, a normal function must be used
        countPlusLocalState (state) {
          return state.count + this.localCount
        }
    }
})

단순히 상태 속성관찰한 다음 해당 속성의 변경에 따라 구성 요소 내에서 작업하려면 아래 예를 참조하십시오.

store.js:

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

이 시나리오를 하고 있다.boolean신청서의 다른 장소에서 변경하고자 하는 재산을 다음과 같이 명시한다.

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

자, 만약 내가 다른 요소에서 그 주 재산을 보고 지역 재산을 변경해야 한다면, 나는 다음 사항을 쓰겠다.mounted스위치:

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

우선, 나는 주의 재산에 감시자를 설정하고 콜백 기능에서 나는 그것을 사용한다.value 의 일부를 localProperty.

도움이 되었으면 좋겠어!

난 말 그대로 모든 걸 시도했어

이론

나는 어떤 이유로 부터 사물에 대한 변화를 발견했다.$store반드시 a를 유발하는 것은 아니다..watch방법의나의 해결책은 하는 것이었다.

  • 저장하다
    • 변경 사항을 구성 요소로 전파해야 하지만 전파하지 않는 복합 데이터 세트 생성
    • 에 대한 in 카터 생성에 state플래그 역할을 하며, 플래그는 변경 사항을 감시할 때 구성요소에 전파한다.
    • 메서드 생성 위치$store.mutators복잡한 데이터 집합을 변경하고 카운터 플래그를 늘리다
  • 구성 요소
    • 다음에서 변경 사항 관찰$store.state 변경이 감지되면 에서 로컬로 관련된 반응적 변경 사항을 업데이트하십시오.$store.state복합 데이터 세트
    • 을 한다.$store.state의 데이터셋을 사용하여$store.mutators방법

실행

이것은 다음과 같은 방식으로 구현된다.

저장하다

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);
  }

실행 가능한 데모

복잡하지만 기본적으로 여기서는 플래그가 변경되는 것을 주시하고 있으며, 그 다음에 로컬 데이터를 업데이트하여 해당 객체에 저장된 중요한 변경사항을 반영하고 있다.$state

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>

typecript를 사용하는 경우:

import { Watch } from "vue-property-decorator";

..

@Watch("$store.state.something")
private watchSomething() {
   // use this.$store.state.something for access
   ...
}

값 변경을 감시하고 설정하여 저장소 변수의 로컬 상태를 만드십시오.Form-input v-model에 대해 로컬 변수가 변경되는 것은 저장 변수를 직접 변경하지 않는다.

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

가게의 변화를 지켜보는 가장 좋은 방법은mapGetters가브리엘의 말대로그러나 끝까지 할 수 없는 경우가 있다.mapGetters예를 들어, 다음 매개 변수를 사용하여 스토어에서 무언가를 가져오려는 경우:

getters: {
  getTodoById: (state, getters) => (id) => {
    return state.todos.find(todo => todo.id === id)
  }
}

그런 경우에는 사용할 수 없다.mapGetters 대신 다음과 같은 작업을 시도하십시오.

computed: {
    todoById() {
        return this.$store.getters.getTodoById(this.id)
    }
}

하지만 불행히도todoById 다음에 한해서만 업데이트될 것이다.this.id바뀌다

이러한 경우 구성 요소를 업데이트하려면 다음을 사용하십시오.this.$store.watch 공씨가 제공한 해결책또는 구성 요소를 의식적으로 처리하고 업데이트this.id업데이트해야 할 때todoById.

구성 요소 내부에서 계산된 함수를 생성하십시오.

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내포된 데이터를 가진 다음handler옵션이 더 도움이 될 것이다.

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

이렇게 하면 스토어의 모든 중첩 값을 볼 수 있다.my_state.

다음 스토어 돌연변이를 구독할 수도 있다.

store.subscribe((mutation, state) => {
  console.log(mutation.type)
  console.log(mutation.payload)
})

https://vuex.vuejs.org/api/#1906

Vuex 작업, 게터, 계산된 속성관찰자의 조합을 사용하여 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 데모를 참조하십시오.

주 차원에서 시청하고 싶을 때는 다음과 같이 할 수 있다.

let App = new Vue({
    //...
    store,
    watch: {
        '$store.state.myState': function (newVal) {
            console.log(newVal);
            store.dispatch('handleMyStateChange');
        }
    },
    //...
});

계산에 게이터를 사용한 후 이를 시청하고 필요한 작업을 수행하십시오.

    computed:{
    ...mapGetters(["yourGetterName"])
 },
 watch: {
    yourGetterName(value) {
       // Do something you need
    },

  }

현악 상태에서 Vue watch

상태:

$store.state.local_store.list_of_data

내부 구성 요소

  watch: {
       
       '$store.state.local_store.list_of_data':{//<----------your state call in string
        handler(){
            console.log("value changeing in party sales entry"); //<---do your stuff here
        },
        deep:true
       }

    },

vue 구성 요소에서 mapState를 사용하여 저장소에서 상태를 가져오십시오.

구성 요소:

computed: mapState([
  'my_state'
])

어디에my_state상점의 변수다.

====== 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: {}
})

나는 이렇게 사용했고 그것은 효과가 있다:

store.js:

const state = {
  createSuccess: false
};

돌연변이.js

[mutations.CREATE_SUCCESS](state, payload) {
    state.createSuccess = payload;
}

actions.js

async [mutations.STORE]({ commit }, payload) {
  try {
    let result = await axios.post('/api/admin/users', payload);
    commit(mutations.CREATE_SUCCESS, user);
  } catch (err) {
    console.log(err);
  }
}

getters.js.

isSuccess: state => {
    return state.createSuccess
}

저장소의 상태를 사용하는 구성 요소:

watch: {
    isSuccess(value) {
      if (value) {
        this.$notify({
          title: "Success",
          message: "Create user success",
          type: "success"
        });
      }
    }
  }

사용자 제출 양식에 따라 조치 STORE가 호출되며, 생성된 성공 후 CREATE_SUPTURE 돌연변이가 실행된다.Turn createSuccessful은 참이며 구성 요소에서 watcher는 값이 변경되었음을 확인하고 알림을 트리거한다.

성공getters.js에서 선언하는 이름과 일치해야 한다.

디버드워치로도 안전하게 시청할 수 있다(vue 사용 기능)

  debouncedWatch(
    lines,
    () => {
      console.log('changed');
    },
    500,
  );

참조URL: https://stackoverflow.com/questions/43270159/how-to-watch-store-values-from-vuex

반응형