Vuex 存储状态不更新屏幕/Vue-Native
Vuex store state not updating screen / Vue-Native
我正在使用 Vue-Native 构建一个具有多个屏幕的简单应用程序(使用 Vue Native Router)。我有这样的情况,我连接到屏幕 A 中的 WebSocket,它侦听消息,我需要这些更新在屏幕 A 和屏幕 B 中可用。
因此,在我对全局变量和原型属性一无所知之后,我遇到了 Vuex,它似乎完全可以满足我的需要。
确实它可以很好地更新屏幕上的属性,但它似乎没有反应并更新屏幕。
store.js:
import Vue from "vue-native-core";
import Vuex from "vuex"
Vue.use(Vuex);
export default new Vuex.Store({
state: {
imageUri: ["", "", "", ""]
},
mutations: {
updateImage (state, data) {
state.imageUri[data.index] = data.url;
}
}
});
ScreenA.vue 在脚本标签中:
import store from "./store.js"
export default {
[...]
methods: {
[...]
handleMessage: function(message){
var data = message.data.split("#", 2);
var value = data[1];
console.log("New msg");
if(data[0] == "init"){
this.connectionMs = Date.now()-value;
this.connectionStatus = 2;
}else if(data[0] == "img"){
var current = this.cImg;
this.cImg = (this.cImg+1)%4;
var dataUrl = "data:image/jpeg;base64,"+value.substring(2, value.length-1);
store.commit('updateImage', {index: current, url: dataUrl}); //<- Relevant line
}
},
[...]
}
}
ScreenB.vue:
<template>
<view :style="{marginTop: 40}">
<image resizeMode="contain" :style="{ width: '100%', height: 200 }" :source="{uri: imageUri[0]}"/>
<image resizeMode="contain" :style="{ width: '100%', height: 200 , marginTop: -200}" :source="{uri: imageUri[1]}"/>
<image resizeMode="contain" :style="{ width: '100%', height: 200 , marginTop: -200}" :source="{uri: imageUri[2]}"/>
<image resizeMode="contain" :style="{ width: '100%', height: 200 , marginTop: -200}" :source="{uri: imageUri[3]}"/>
<touchable-opacity :on-press="btnPress">
<text>Press me! {{imageUri[0]}}</text>
</touchable-opacity>
</view>
</template>
<script>
import store from "./store.js"
export default {
props: {
navigation: {
type: Object
}
},
computed:{
imageUri: function(){
return store.state.imageUri;
}
},
methods: {
btnPress: function(){
console.log("ImgUrl0 -> "+this.imageUri[0]);
},
},
}
</script>
一旦商店中的 vuex 状态发生变化(console.log 打印新值),计算的 属性 就会正确更新,但屏幕上的渲染数据(文本和图像元素)保留旧数据。
有什么办法可以解决这个问题吗?也许是一种完全不同的跨屏幕同步动态数据的方法?
您的突变仅更新 state.imageUri[data.index]
,不会更改 state.imageUri
的引用。这意味着 state.imageUri
仍然指向旧引用,并且 Vue 无法检测到此更新。这是 Vue's gotchas
之一
一个解决方案是使用 JSON.parse(JSON.stringify())
对 state.imageUri
数组进行深度复制
export default new Vuex.Store({
state: {
imageUri: ["", "", "", ""]
},
mutations: {
updateImage (state, data) {
state.imageUri[data.index] = data.url;
state.imageUri = JSON.parse(JSON.stringify(state.imageUri))
}
}
});
我正在使用 Vue-Native 构建一个具有多个屏幕的简单应用程序(使用 Vue Native Router)。我有这样的情况,我连接到屏幕 A 中的 WebSocket,它侦听消息,我需要这些更新在屏幕 A 和屏幕 B 中可用。
因此,在我对全局变量和原型属性一无所知之后,我遇到了 Vuex,它似乎完全可以满足我的需要。
确实它可以很好地更新屏幕上的属性,但它似乎没有反应并更新屏幕。
store.js:
import Vue from "vue-native-core";
import Vuex from "vuex"
Vue.use(Vuex);
export default new Vuex.Store({
state: {
imageUri: ["", "", "", ""]
},
mutations: {
updateImage (state, data) {
state.imageUri[data.index] = data.url;
}
}
});
ScreenA.vue 在脚本标签中:
import store from "./store.js"
export default {
[...]
methods: {
[...]
handleMessage: function(message){
var data = message.data.split("#", 2);
var value = data[1];
console.log("New msg");
if(data[0] == "init"){
this.connectionMs = Date.now()-value;
this.connectionStatus = 2;
}else if(data[0] == "img"){
var current = this.cImg;
this.cImg = (this.cImg+1)%4;
var dataUrl = "data:image/jpeg;base64,"+value.substring(2, value.length-1);
store.commit('updateImage', {index: current, url: dataUrl}); //<- Relevant line
}
},
[...]
}
}
ScreenB.vue:
<template>
<view :style="{marginTop: 40}">
<image resizeMode="contain" :style="{ width: '100%', height: 200 }" :source="{uri: imageUri[0]}"/>
<image resizeMode="contain" :style="{ width: '100%', height: 200 , marginTop: -200}" :source="{uri: imageUri[1]}"/>
<image resizeMode="contain" :style="{ width: '100%', height: 200 , marginTop: -200}" :source="{uri: imageUri[2]}"/>
<image resizeMode="contain" :style="{ width: '100%', height: 200 , marginTop: -200}" :source="{uri: imageUri[3]}"/>
<touchable-opacity :on-press="btnPress">
<text>Press me! {{imageUri[0]}}</text>
</touchable-opacity>
</view>
</template>
<script>
import store from "./store.js"
export default {
props: {
navigation: {
type: Object
}
},
computed:{
imageUri: function(){
return store.state.imageUri;
}
},
methods: {
btnPress: function(){
console.log("ImgUrl0 -> "+this.imageUri[0]);
},
},
}
</script>
一旦商店中的 vuex 状态发生变化(console.log 打印新值),计算的 属性 就会正确更新,但屏幕上的渲染数据(文本和图像元素)保留旧数据。
有什么办法可以解决这个问题吗?也许是一种完全不同的跨屏幕同步动态数据的方法?
您的突变仅更新 state.imageUri[data.index]
,不会更改 state.imageUri
的引用。这意味着 state.imageUri
仍然指向旧引用,并且 Vue 无法检测到此更新。这是 Vue's gotchas
一个解决方案是使用 JSON.parse(JSON.stringify())
对 state.imageUri
数组进行深度复制
export default new Vuex.Store({
state: {
imageUri: ["", "", "", ""]
},
mutations: {
updateImage (state, data) {
state.imageUri[data.index] = data.url;
state.imageUri = JSON.parse(JSON.stringify(state.imageUri))
}
}
});