raf*_*fff 129 javascript vue.js vuex vuejs2
我使用vuex和vuejs 2在一起.
我是新手vuex,我想看一个store变量.
我想watch在我的功能中添加功能vue component
这是我到目前为止:
import Vue from 'vue';
import {
MY_STATE,
} from './../../mutation-types';
export default {
[MY_STATE](state, token) {
state.my_state = token;
},
};
Run Code Online (Sandbox Code Playgroud)
我想知道是否有任何变化 my_state
我如何store.my_state在我的vuejs组件中观看?
Ana*_*azy 138
比方说,例如,你有一篮水果,每次你从篮子里添加或删除水果,你想(1)显示有关水果数量的信息,但你也(2)想要得到通知一些花哨时尚的水果数......
水果计数component.vue
<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, yaay!`)
}
}
}
</script>
Run Code Online (Sandbox Code Playgroud)
请注意,watch对象中函数的名称必须与对象中函数的名称匹配computed.在上面的例子中,名称是count.
监视属性的新旧值将作为参数传递给监视回调(计数函数).
篮子商店看起来像这样:
水果basket.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
}
}
// Obvously you would need some mutations and actions,
// but to make example cleaner I'll skip this part.
})
export default basket
Run Code Online (Sandbox Code Playgroud)
您可以在以下资源中阅读更多内容:
Gab*_*ert 60
您不应该使用组件的观察者来听取状态变化.我建议您使用getter函数,然后将它们映射到组件中.
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters({
myState: 'getMyState'
})
}
}
Run Code Online (Sandbox Code Playgroud)
在你的商店:
const getters = {
getMyState: state => state.my_state
}
Run Code Online (Sandbox Code Playgroud)
您应该能够通过this.myState在组件中使用来收听对商店所做的任何更改.
https://vuex.vuejs.org/en/getters.html#the-mapgetters-helper
GON*_*ONG 36
如上所述,直接在商店中观看更改并不是一个好主意
但在一些非常罕见的情况下,它可能对某人有用,所以我会留下这个答案.对于其他情况,请参阅@ 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.
}
);
Run Code Online (Sandbox Code Playgroud)
更多细节:https://vuex.vuejs.org/en/api.html#vuex-store-instance-methods
yea*_*xon 14
我认为提问者想要使用Vuex手表.
this.$store.watch(
(state)=>{
return this.$store.getters.your_getter
},
(val)=>{
//something changed do something
},
{
deep:true
}
);
Run Code Online (Sandbox Code Playgroud)
Jak*_*cki 11
如果你只想看一个国家的财产,然后将组件内采取相应的行动,以该财产的变化,然后看下面的例子。
在store.js:
export const state = () => ({
isClosed: false
})
export const mutations = {
closeWindow(state, payload) {
state.isClosed = payload
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我将创建一个boolean状态属性,我将在应用程序的不同位置对其进行更改,如下所示:
this.$store.commit('closeWindow', true)
Run Code Online (Sandbox Code Playgroud)
现在,如果我需要在其他组件中查看该状态属性,然后更改本地属性,我会在mounted钩子中写入以下内容:
mounted() {
this.$store.watch(
state => state.isClosed,
(value) => {
if (value) { this.localProperty = 'edit' }
}
)
}
Run Code Online (Sandbox Code Playgroud)
首先,我在 state 属性上设置了一个观察者,然后在回调函数中我使用该value属性的 来更改localProperty.
我希望它有帮助!
小智 10
如果您使用打字稿,那么您可以:
import { Watch } from "vue-property-decorator";
..
@Watch("$store.state.something")
private watchSomething() {
// use this.$store.state.something for access
...
}Run Code Online (Sandbox Code Playgroud)
这适用于所有无法用吸气剂解决问题并真正需要观察者的人,例如与非第三方的东西交谈(请参阅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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果它只是关于组合本地和全局状态,mapState的doc也提供了一个例子:
computed: {
...mapState({
// to access local state with `this`, a normal function must be used
countPlusLocalState (state) {
return state.count + this.localCount
}
}
})
Run Code Online (Sandbox Code Playgroud)
就像这样简单:
watch: {
'$store.state.drawer': function() {
console.log(this.$store.state.drawer)
}
}
Run Code Online (Sandbox Code Playgroud)
我真的尝试了一切来让它工作。
我发现由于某种原因,对对象的更改$store不一定会触发.watch方法。我的解决方法是
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++;
}
}
});
Run Code Online (Sandbox Code Playgroud)
成分
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);
}
Run Code Online (Sandbox Code Playgroud)
这很复杂,但基本上在这里我们正在观察标志的变化,然后更新本地数据以反映存储在 $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)
}
}
}
})Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
在计算中使用你的吸气剂然后观察它并做你需要的事情
computed:{
...mapGetters(["yourGetterName"])
},
watch: {
yourGetterName(value) {
// Do something you need
},
}
Run Code Online (Sandbox Code Playgroud)
观察商店变化的最好方法是使用mapGettersGabriel 所说的。但是有一种情况,你不能通过mapGetters例如你想使用参数从商店获取一些东西:
getters: {
getTodoById: (state, getters) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您不能使用mapGetters. 你可以尝试做这样的事情:
computed: {
todoById() {
return this.$store.getters.getTodoById(this.id)
}
}
Run Code Online (Sandbox Code Playgroud)
但不幸的todoById 是只有在this.id更改时才会更新
如果您希望在这种情况下更新组件,请使用this.$store.watch 龚提供的解决方案。或者有意识地处理你的组件并this.id在需要更新时更新todoById。
小智 6
在组件内部,创建一个计算函数
computed:{
myState:function(){
return this.$store.state.my_state; // return the state value in `my_state`
}
}
Run Code Online (Sandbox Code Playgroud)
现在可以查看计算出的函数名称,例如
watch:{
myState:function(newVal,oldVal){
// this function will trigger when ever the value of `my_state` changes
}
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
这将监视 store 中的所有嵌套值my_state。
您可以使用 Vuex actions、getter、计算属性和观察者的组合来监听 Vuex 状态值的变化。
HTML 代码:
<div id="app" :style='style'>
<input v-model='computedColor' type="text" placeholder='Background Color'>
</div>
Run Code Online (Sandbox Code Playgroud)
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()}`)
}
}
})
Run Code Online (Sandbox Code Playgroud)
通过观察和设置值更改来创建商店变量的Local状态。这样,表单输入v模型的局部变量更改不会直接更改存储变量。
data() {
return {
localState: null
};
},
computed: {
...mapGetters({
computedGlobalStateVariable: 'state/globalStateVariable'
})
},
watch: {
computedGlobalStateVariable: 'setLocalState'
},
methods: {
setLocalState(value) {
this.localState = Object.assign({}, value);
}
}
Run Code Online (Sandbox Code Playgroud)
You could also subscribe to the store mutations:
store.subscribe((mutation, state) => {
console.log(mutation.type)
console.log(mutation.payload)
})
Run Code Online (Sandbox Code Playgroud)
https://vuex.vuejs.org/api/#subscribe
| 归档时间: |
|
| 查看次数: |
131550 次 |
| 最近记录: |