如何将更新的数据传递给已经渲染的子 vue 组件
Posted
技术标签:
【中文标题】如何将更新的数据传递给已经渲染的子 vue 组件【英文标题】:How to pass updated data to already child vue component rendered 【发布时间】:2019-07-15 12:48:23 【问题描述】:我正在尝试将一些 vars 更新到父组件中。我的情况是这样的:
我有一个父组件:
import LugarListComponent from './LugarListComponent';
import LugarAddComponent from './LugarAddComponent'
export default
components:
'lugar-list-component' : LugarListComponent,
'lugar-add-component' : LugarAddComponent,
,
data()
return
show: false,
nombre: '',
desc : '',
,
methods:
showComponent: function ()
this.show = true;
,
hideComponent: function ()
this.show = false;
,
setLugar: function(lugar)
this.show = true;
,
mounted()
//console.log('Component mounted.')
<template>
<div class="container">
<h3>Lugares</h3>
<div style="text-align: right">
<button type="button" class="btn btn-primary" v-show="!show" v-on:click.prevent="showComponent"><i class="fa fa-plus"></i> Adicionar</button>
<button type="button" class="btn btn-success" v-show="show" v-on:click.prevent="hideComponent"><i class="fa fa-arrow-left"></i> Regresar</button>
</div>
<br>
<lugar-list-component v-show="!show" @setLugar="setLugar"></lugar-list-component>
<lugar-add-component v-show="show" @hideComponent="hideComponent"></lugar-add-component>
</div>
</template>
该组件有两个子组件,用于列出地点的 lugar-list 和用于添加地点的 lugar-add。当我显示其中一个时,我有一个用于控制的 show var。
我想编辑一个地方,但我想将数据发送到 lugar-add 以将他的值显示到此组件中,但我没有找到任何解决方案将变量更新为 lugar-add。这里我展示了这个组件的代码。
对于 lugar-add
export default
data()
return
image: '',
nombre: '',
desc : ''
,
methods:
onImageChange(e)
let files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.createImage(files[0]);
,
createImage(file)
let reader = new FileReader();
let vm = this;
reader.onload = (e) =>
vm.image = e.target.result;
;
reader.readAsDataURL(file);
,
uploadImage()
axios.post('/lugar',
image: this.image,
nombre: this.nombre,
desc: this.desc
).then(response =>
if(response.status == 200)
this.$emit('hideComponent')
);
,
setAttributes(lugarEdit)
console.log('disparado');
this.nombre = lugarEdit.nombre;
this.desc = lugarEdit.desc;
,
mounted()
//console.log('Component mounted.');
this.$on(
'setAttributes',
function(lugar)
this.nombre = lugar.nombre;
this.desc = lugar.desc;
);
<template>
<div class="container">
<div class="form-group">
<label>Nombre</label>
<input type="text" v-model="nombre" class="form-control" placeholder="Nombre del lugar">
</div>
<div class="form-group">
<label for="descTexArea">Descripción</label>
<textarea v-model="desc" class="form-control" id="descTexArea" rows="3"></textarea>
</div>
<div class="form-group">
<label for="exampleFormControlFile1">Subir imágenes</label>
<input type="file" v-on:change="onImageChange" class="form-control-file" id="exampleFormControlFile1">
</div>
<div class="form-group">
<button type="button" class="btn btn-primary" @click="uploadImage">Adicionar</button>
</div>
<div class="col-md-3" v-if="image">
<img :src="image" class="img-responsive" >
</div>
</div>
</template>
这里我使用事件来隐藏这个组件并显示 lugar-list 组件。这是 lugar-list 的代码
export default
name: 'lugar-list-component',
data:function()
return
listLugares : [],
id : '',
,
methods:
getLugares: function ()
fetch('/lugar')
.then(response => response.json())
.then(res =>
this.listLugares = res;
)
,
setId: function(id)
this.id = id;
,
removeLugar: function(id)
this.id = id;
axios.delete('lugar/'+id)
.then(response =>
this.getLugares();
);
,
editLugar: function(id)
this.id = id;
axios.get('lugar/'+id)
.then(response =>
this.$emit('setLugar',response);
);
,
,
mounted()
this.getLugares();
<template>
<div class="container">
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Nombre</th>
<th scope="col">Desc.</th>
<th scope="col">Fecha</th>
<th scope="col">Acciones</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in listLugares">
<th scope="row"> index+1 </th>
<td> item.nombre </td>
<td> item.desc </td>
<td> item.created_at </td>
<td>
<button type="button" class="btn btn-success" v-on:click.prevent="editLugar(item.id)"><i class="fa fa-edit"></i> Editar</button>
<button type="button" class="btn btn-danger" v-on:click.prevent="removeLugar(item.id)"><i class="fa fa-remove"></i> Eliminar</button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
希望你能理解我。谢谢。
【问题讨论】:
【参考方案1】:我没有找到其他使用带参数的路由的解决方案,我相信这是最好的解决方案。
这是我的路线
path: '/lugar', component: require('./components/lugar/LugarComponent').default,
children: [
path: '', component: LugarList ,
path: 'add/:id?',
name: 'lugarAdd',
component: LugarAdd
,
path: 'list',
component: LugarList
]
添加地点的路线有一个可选参数。
现在,在 Add 组件中,我使用以下代码获取参数:
this.id = this.$route.params.id;
this.modeEdit = true;
axios.get('/lugar/'+this.id)
.then(response =>
this.nombre = response.data.nombre;
this.desc = response.data.desc;
for(let i = 0; i<response.data.images.length; i++)
this.image.push(response.data.images[i]);
);
当我获得地点 ID 时,我会通过 axios 请求其信息。
【讨论】:
【参考方案2】:从第一个子组件发出一个事件来更新父组件。然后将要更新的值作为道具传递给第二个子元素。
【讨论】:
我对此进行了测试。问题是我认为该组件确实被渲染了,我在 lugar-list 组件中有一个事件,用于通知父组件我要编辑的位置,“editLugar”。这个函数触发了父级的setLugar函数,这里我得到了位置,但我不知道如何发送这个新数据来添加组件。 我不确定你的意思。您只是想在子组件上触发一个动作,或者向它添加一些数据?如果你想添加一些数据,那么你应该将父组件中的所有数据都放在一个数据中。然后在从第一个孩子接收数据时,附加/更新父母的数据。然后,您将数据(始终是最新的)从父级传递给第二个子级作为道具。对 prop 的更改将自动反映在子组件中。以上是关于如何将更新的数据传递给已经渲染的子 vue 组件的主要内容,如果未能解决你的问题,请参考以下文章