【发布时间】: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