VueJS 计算属性未在 DOM 上更新

Posted

技术标签:

【中文标题】VueJS 计算属性未在 DOM 上更新【英文标题】:VueJS computed property not updating on DOM 【发布时间】:2018-08-28 13:13:56 【问题描述】:

我正在尝试使用 VueJS 进行文件上传。 当一个文件被添加到输入字段时,它被缓冲并保存在 vuex 存储中。

我很肯定状态会更新,这显示在 vue-devtool 中,我添加了一个按钮来检查它。

但是,DOM 不会在状态更改时重新渲染。我用缓冲区数组和普通字符串都试过了。 (当我单击 vue-dev 工具中的提交按钮时,它会更新 dom)

请参阅此屏幕截图以演示问题(这是在选择文件并单击“控制台日志状态”按钮之后)。 Demonstration

组件

<template>
  <div id="home">
    <h3>Upload Book (pdf)</h3>
    <form v-on:submit="">
      <input v-on:change="captureFile" type="file" placeholder="Select file..." />
      <button type="submit">Upload</button>
      <p>
        <button v-on:click="consoleLog">Console log state</button>
        filebuffer
      </p>
    </form>

  </div>
</template>

<script>
export default 
  name: 'home',
  computed: 
    filebuffer () 
      return this.$store.state.fileBuffer
    
  ,
  methods: 
    captureFile (event) 
      let file = event.target.files[0]
      let reader = new window.FileReader()
      reader.readAsArrayBuffer(file)
      reader.onloadend = () => this.$store.dispatch('loadBuffer', reader)
    ,
    consoleLog () 
      console.log(this.$store.state.fileBuffer)
    
  

</script>

商店

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'

Vue.use(Vuex)

export const store = new Vuex.Store(
  strict: true,
  state,
  mutations: 
    saveBuffer (state, payload) 
      state.fileBuffer = 'this will not update on the DOM'
      console.log('saveBuffer committed', payload)
    
  ,
  actions: 
    loadBuffer (commit, payload) 
      let buffer = Buffer.from(payload.result)
      commit('saveBuffer', buffer)
    
  
)

【问题讨论】:

两种可能性。首先,如果fileBuffer 在状态之前 上不存在,则将其添加到saveBuffer(例如作为空值),那么您已陷入change detection caveat。其次,Vue 不能很好地处理不是纯 javascript 对象的对象,并且无法检测到 FileReader 对象的更改。它应该能够检测到新的引用(考虑到上述警告),但对 FileReader 属性的更改不会是被动的。 我的状态是在一个单独的文件中预定义的(空值),我只是懒得把它放进去。它包括 fileBuffer: null 。它正确地检测到何时上传了新文件,它将通过动作/变异流程。不更新的一件事是 DOM。我很困惑:(。 谢谢,你让我查看了我的 state.js 文件,我意识到我忘了导出我的状态。我现在感觉完全迟钝了:D 浪费了我生命中的 4 个小时,哈哈! 别担心 :) 我们都去过那里! 【参考方案1】:

您需要使用Getters。

computed: 
  filebuffer () 
    return this.$store.getters.filebuffer;
  

在您的 store 文件中

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex)

// State
const state = 
    fileBuffer : '',  


// Mutate the State
const mutations = 
     saveBuffer (state, value) 
        state.fileBuffer = value
  

// Access The State
const getters = 
    fileBuffer : state => 
        return state.fileBuffer 
    


const actions = 
   loadBuffer (commit, payload) 
     let buffer = Buffer.from(payload.result)
     commit('saveBuffer', buffer)
   


const module = 
    state,
    getters,
    mutations,
    actions
;

export default module;

希望这有助于解决您的问题。

【讨论】:

感谢您的宝贵时间。我实际上只是忘记导出我的状态.. 我很愚蠢:D

以上是关于VueJS 计算属性未在 DOM 上更新的主要内容,如果未能解决你的问题,请参考以下文章

计算属性未在道具更改时更新

vuejs 计算属性 - 何时触发更新?

Vuejs:计算属性不更新视图

VueJS:属性或方法......未在实例上定义,但在渲染期间引用

Vuejs2:数组更改时如何重新渲染数组计算属性

(Vuejs)属性或方法未在实例上定义,但在渲染期间引用