如何将更新的数据传递给已呈现的子Vue组件

时间:2019-02-21 14:52:19

标签: laravel vue.js components

我正在尝试将某些var从父级更新为组件。我的情况是这样:

我有一个父级组件:

    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用于添加位置。显示其中一个时,我有一个用于控制的显示变量。

我想编辑一个位置,但是我想将数据发送到lugar-add以将其值显示到此组件中,但是我找不到任何将vars更新为lugar-add的解决方案。在这里,我显示了这些组件的代码。

添加lugar

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&oacute;n</label>
            <textarea v-model="desc" class="form-control" id="descTexArea" rows="3"></textarea>
        </div>

        <div class="form-group">
            <label for="exampleFormControlFile1">Subir im&aacute;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" height="70" width="90">
        </div>
    </div>
</template>

在这里,我使用event来隐藏此组件并显示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>

我希望你能理解我。谢谢。

2 个答案:

答案 0 :(得分:0)

从第一个子组件发出事件以更新父项的道具。然后将要更新的值作为prop传递给secund子元素。

答案 1 :(得分:0)

我找不到其他使用带参数的路由的解决方案,我认为这是最好的解决方案。

这是我的路线

{
        path: '/lugar', component: require('./components/lugar/LugarComponent').default,
        children: [
            { path: '', component: LugarList },
            {
                path: 'add/:id?',
                name: 'lugarAdd',
                component: LugarAdd
            },
            {
                path: 'list',
                component: LugarList
            }
        ]
    }

添加地点的路线具有可选参数。

现在,使用以下代码将代码添加到“添加”组件中:

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请求其信息。