Vuex 商店状态不更新屏幕/Vue-Native

Posted

技术标签:

【中文标题】Vuex 商店状态不更新屏幕/Vue-Native【英文标题】:Vuex store state not updating screen / Vue-Native 【发布时间】:2019-01-25 12:47:18 【问题描述】:

我正在使用 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;
      
    
  );

Script-Tag 中的 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 打印新值),计算属性就会正确更新,但屏幕上呈现的数据(文本和图像元素)仍保留旧数据。

有什么办法可以解决这个问题吗?也许是一种完全不同的方法来跨屏幕同步我的动态数据?

【问题讨论】:

【参考方案1】:

你的突变只更新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))
          
        
      );

【讨论】:

以上是关于Vuex 商店状态不更新屏幕/Vue-Native的主要内容,如果未能解决你的问题,请参考以下文章

Vuex 提交不更新状态

VueJS - Vuex 状态更新时组件不更新

Vue3 Vuex状态更改不更新计算值

监听getter的Vuex计算属性不更新

Vuex 商店自动更新

vuex 商店不更新组件