我有具有这种结构的三个组件
1.ParrentComponent(
-1.ChildComponent
-2.Child
)
1.子组件通过文件输入加载图像并在该 Controller 中进行预览。单击提交按钮后,我需要将此 blob 图像发送给第二个 child 并在那里显示预览。
我的问题是,当我将图像发送到图像中的第二个子网址时,图像是相同的,但图像不显示,仅显示 alt
1. child :
<template>
<div id="insert-component">
<div id="insert-new" >
<h2 class="text-md-left">Nová kategória</h2>
<div class="mt-2 text-left">
<a href="#" id="img-button" class=" d-flex flex-wrap" v-on:click.stop="loadImage()">
<img v-bind:src="category_img" alt="logo" id="preview">
<input type="file" class="d-none" id="load-category-image" v-on:input="handleFileSelected">
<button class="btn btn-dark btn-block" >Pridať obrázok</button>
</a>
<small class="text-danger d-none error" id="img-error">Súbor musí byť png, jpg alebo jpeg</small>
</div>
<div class="form-group mt-2 text-left">
<div>
<label for="category_name">Názov kategórie:</label>
<input type="text" required name="name" class="form-control" v-model="category_name" id="category_name">
<small class="text-danger d-none error" id="name-error">*Názov je povinný</small>
</div>
<label for="category_description" class="mt-2">Popis kategórie:</label>
<textarea name="description" class="form-control" rows="4" v-model="category_description" id="category_description">
</textarea>
</div>
</div>
<button class="btn btn-success btn-block my-2" v-on:click.prevent="submit()">Pridať kategóriu</button>
</div>
</template>
<script>
export default {
name: "InsertComponent",
props: [ 'updateTableData' ],
data: function () {
return {
category_name: "",
category_description: "",
category_img:"/storage/images/no_image.png",
file:null
}
},
methods: {
loadImage(){
document.getElementById('load-category-image').click();
},
submit(){
if(this.checkIfEmptyById('category_name')){
this.showErrors('name-error');
return
}
let item = this.createNewItem();
this.updateTableData(item);
this.clearInputs();
},
createNewItem(){
return {
category_img: this.category_img,
category_name: this.category_name,
category_description: this.category_description,
created_at: null,
updated_at: null,
id: null,
file:this.file
};
},
clearInputs(){
this.category_name="";
this.category_description="";
this.category_img="/storage/images/no_image.png";
},
handleFileSelected() {
let loadedFile = document.getElementById('load-category-image').files[0];
if(this.checkIfFileIsImage(loadedFile))
{
this.file = loadedFile;
//this.category_img="/storage/images/"+loadedFile.name;
this.changeImagePreview();
}
else{
//show image error
let imgError = document.getElementById('img-error');
imgError.classList.remove('d-none');
}
},
checkIfFileIsImage(file){
const acceptedImageTypes = ['image/jpg', 'image/jpeg', 'image/png'];
return acceptedImageTypes.includes(file['type']);
},
changeImagePreview(){
let loadedFile = document.getElementById('load-category-image').files;
this.category_img = URL.createObjectURL(loadedFile[0]);
},
},
}
</script>
第二个 child :
<template>
<div class="text-center">
<b-table striped hover :items="items" :fields="fields">
<template v-slot:cell(category_img)="data">
<img v-bind:src="'/storage/images/'+data.item.category_img" alt="img" width="50px" height="50px" class="rounded-circle">
</template>
<template v-slot:cell(category_name)="data">
{{data.item.category_name | capitalize}}
</template>
<template v-slot:cell(category_description)="data">
{{data.item.category_description | capitalize}}
</template>
<template v-slot:cell(actions)="data">
<div class="d-flex justify-content-center">
<a href="#" class="btn btn-info mr-1"><i class="fas fa-edit"></i></a>
<a href="#" class="btn btn-danger"><i class="fas fa-times-circle"></i></a>
</div>
</template>
</b-table>
</div>
</template>
<script>
export default {
name:"TableComponent",
props: ['tableData'],
data() {
return {
fields: [
{
key: 'category_img',
label:'Img',
sortable: false
},
{
key: 'category_name',
label:'Name',
tdClass: 'capitalize-first-letter',
sortable: true,
variant: 'dark'
},
{
key: 'category_description',
thClass: 'd-none d-md-block',
tdClass: 'd-none d-md-block text-left',
label:'Description',
sortable: false,
},
{
key: 'actions',
sortable: false,
}
],
items: this.tableData
}
},
父组件只是在这些组件之间传递数据,数据传递得好并不重要。问题就出在那个图像上。谢谢帮助
最佳答案
如果我错了,请纠正,但在你的 Child
中,你将一个函数作为 prop 传递,这在 vue 中是一个反模式。您应该始终遵循 props down event up
设计模式。
无论如何,继续解决你的问题。在您的 Child 2
上,您有以下行
items: this.tableData
此行会将 this.tableData
的值分配给 items
。这只分配给组件的创建的钩子(Hook)部分。如果此表数据发生变化(我相当确定它会发生变化),则 item
变量将不会更新。您应该有一个 watch 来监视 Prop 并重新分配给 item
watch: {
tableData: (value) => {
this.item = value;
}
}
关于javascript - Vue js在子组件之间发送图像blob并显示图像预览,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60747711/