【发布时间】:2021-09-26 23:33:33
【问题描述】:
我在读取文件并将其到达父组件时遇到了以下问题。
首先我在 FileReaderComponent 上有一个 FileInput,当文件被更改时,它会发送一个 emit('change', file.content)。
顶部组件获取 file.content 并将其设置为 FileViewerComponent 的 Input Prop。
到目前为止,它按预期工作。但是当我添加第二个 FileReaderComponent 时,它的 Content 应该显示在第二个 FileViewerComponent 中。
但它总是使用第一个 FileReaderComponent 中的 @change。
我对 Vue 很陌生。我建立了一个最小的例子来展示: 相同的行为。当我使用第二个 FileReaderComponent 时,它应该将数据放入 readerOutput2 但出于某种原因它会将数据放入 readerOutput1。
我不知道我做错了什么。
App.vue
<template>
<!-- <img alt="Vue logo" src="./assets/lpdLogo.svg" style="width: 100px; fill: green;"> -->
<FileReaderComponent @change="data.readerOutput1 = $event"/>
<FileViewerComponent v-model:input="data.readerOutput1"/>
<FileReaderComponent @change="data.readerOutput2 = $event"/>
<FileViewerComponent v-model:input="data.readerOutput2"/>
</template>
<script>
import FileReaderComponent from './components/FileReaderComponent.vue';
import FileViewerComponent from './components/FileViewerComponent.vue';
import { reactive } from 'vue';
export default {
name: 'App',
components: {
FileReaderComponent,
FileViewerComponent
},
setup () {
const data = reactive({
readerOutput1: '',
readerOutput2: ''
});
function log(toLog) {
console.log(toLog);
}
return { log, data }
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
FileReaderComponent.vue
<template>
<div id="fileUploadComponent" class="inline-flex items-center p-2 rounded border-2 border-yellow-500 m-1">
<input type='file' id="fileInput" name="fileInput" @change="fileUploadChange()" ref="fileInput" class="hidden"/>
<label for="fileInput" class="h-10 w-40 rounded text-gray-300 dark:text-gray-400 bg-gray-700 hover:bg-gray-500 text-xs" style="line-height: 2.5rem">
<span class="block text-center w-full">Datei öffnen</span></label>
<span id="filenamefield" class="inline-block m-2 text-gray-700 dark:text-gray-300">{{file.name}}</span>
</div>
</template>
<script>
import {reactive} from 'vue';
export default {
name: 'FileReaderComponent',
emits: ['inFocus', 'submit', 'change'],
props: {
input: {
type: String,
required: false,
},
},
methods : {
setContent(content) {
console.log('FileUpload, set Content', content)
this.file.content = content;
this.$emit('change', content);
},
fileUploadChange() {
console.log('fileUploadChange triggered');
this.file.input = this.$refs.fileInput.files[0];
this.file.name = this.file.input.name;
let file = this.file.input;
let parent = this;
parent.setContent('Content Loading')
function onloadevent(evt) {
parent.setContent(evt.target.result);
}
if (file) {
var reader = new FileReader();
reader.readAsText(file, "UTF-8");
reader.onload = function (evt) {
onloadevent(evt);
}
reader.onerror = function () {
onloadevent('An Error occurred while reading File');
}
}
}
},
setup(props, {emit}) {
const file = reactive({
name: 'Keine Ausgewählt',
input: Element,
content: String,
})
return {file}
}
}
</script>
<style scoped>
.inputfile {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.inputfile+label {
font-weight: 700;
display: inline-block;
}
input:checked+svg {
display: block;
}
</style>
文件查看器组件
<template>
<div id="fileViewerComponent" class="inline-flex items-center p-2 rounded border-2 border-yellow-500 m-1">
<h3>Input:</h3>
<div id="view">
{{ input }}
</div>
</div>
</template>
<script>
import {reactive} from 'vue';
export default {
name: 'FileViewerComponent',
emits: ['inFocus', 'submit', 'change'],
props: {
input: {
type: String,
required: false,
},
},
methods : {
},
setup(props, {emit}) {
const file = reactive({
name: 'Keine Ausgewählt',
input: Element,
content: String,
})
return {file}
}
}
</script>
<style scoped>
</style>
【问题讨论】:
-
我刚刚重建了您的代码示例 [在 Vue SFC 游乐场:tinyurl.com/kscn7fn3 - 它似乎按预期工作?我可以在每个对应的文件输入下方看到文件内容!
-
感谢您的回复。我发现了问题。 FileInput 的标签指向 id="fileInput" 并使用单击时找到的第一个输入。您可以通过单击第二个 FileInput 旁边的标签在 SFC Playground 中进行测试。
标签: javascript html vue.js vuejs3