【问题标题】:VueJS computed property not updating on DOMVueJS 计算属性未在 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 个小时,哈哈!
  • 别担心 :) 我们都去过那里!

标签: javascript vue.js


【解决方案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
猜你喜欢
  • 2019-07-14
  • 2018-12-11
  • 2021-03-20
  • 2018-07-19
  • 2019-04-18
  • 2020-08-21
  • 2019-12-05
  • 1970-01-01
相关资源
最近更新 更多