将数据从一个组件发送到另一个组件

时间:2018-08-22 15:25:44

标签: vue.js vuejs2 vue-component

嗨,我正在尝试将数据从一个组件发送到另一个组件,但不确定如何处理。

我有一个组件可以遍历一系列项目并显示它们。然后,我有另一个包含表单/输入的组件,这应该将数据提交到另一个组件中的数组。

我不确定将日期发送到其他组件应该做什么,

用于遍历项目的组件

<template>
    <div class="container-flex">
        <div class="entries">

            <div class="entries__header">
                <div class="entries__header__title">
                    <p>Name</p>
                </div>
            </div>

            <div class="entries__content">
                <ul class="entries__content__list">
                    <li v-for="entry in entries">
                        {{ entry.name }}
                    </li>
                </ul>
            </div>

            <add-entry />

        </div>
    </div>
</template>

<script>

import addEntry from '@/components/add-entry.vue'

export default {
    name: 'entry-list',
    components: {
        addEntry
    },
    data: function() {
        return {
            entries: [
                {
                    name: 'Paul'
                }, 
                {
                    name: 'Barry'
                },
                {
                    name: 'Craig'
                },
                {
                    name: 'Zoe'
                }
            ]
        }
    }
}

</script>

用于添加/发送数据的组件

<template>
    <div 
        class="entry-add"
        v-bind:class="{ 'entry-add--open': addEntryIsOpen }">

        <input 
            type="text"
            name="addEntry"
            @keyup.enter="addEntries" 
            v-model="newEntries">

        </input>

        <button @click="addEntries">Add Entries</button>

        <div 
            class="entry-add__btn"
            v-on:click="openAddEntry">
            <span>+</span>
        </div>

    </div>
</template>

<script>

export default {
    name: 'add-entry',
    data: function() {
        return {
            addEntryIsOpen: false,
            newEntries: ''
        }
    },
    methods: {
        addEntries: function() {
            this.entries.push(this.newEntries);
            this.newEntries = '';
        },
        openAddEntry() {
            this.addEntryIsOpen = !this.addEntryIsOpen;
        }
    }
}

</script>

3 个答案:

答案 0 :(得分:0)

在2之间同步属性:

<add-entry :entries.sync="entries"/>

将其作为道具添加到add-entry组件中:

props: ['entries']

然后对2进行浅合并,然后将其发回给父对象:

this.$emit('entries:update', [].concat(this.entries, this.newEntries))

答案 1 :(得分:0)

(这是一条评论,但变得很大了:D)

  

是否可以传递名称密钥?该条目已添加但未显示,因为im循环并输出{{entry.name}}

之所以发生这种情况,可能是因为当您通过参数传递“复杂对象”时,即使您同步了属性,在装入组件时,即使您同步了属性,嵌入的对象/集合也被视为可观察的对象。情况下,数组内的对象是性能友好的,但有时有点烦人,您有两个选择,第一个是声明一个计算属性,该属性返回从父控制器传递的属性,第二个(肮脏和丑陋但可以工作)将JSON.stringify传递给集合,然后JSON.parse将其转换回没有可观察属性的对象

希望这对您有任何帮助。

干杯。

答案 2 :(得分:0)

因此,在@Ohgodwhy的帮助下,我设法使其正常运行。我不确定这是否是正确的方法,但是它似乎确实可以正常工作。如果有,请添加一个更好的解决方案,我将其标记为答案。

我遵循Ohmygod所说的,但是this.$emit('entries:update', [].concat(this.entries, this.newEntries))无效。好吧,我什至不需要添加它。

这是我的add-entry.vue组件

<template>
    <div 
        class="add-entry"
        v-bind:class="{ 'add-entry--open': addEntryIsOpen }">

        <input
            class="add-entry__input"
            type="text"
            name="addEntry"
            placeholder="Add Entry"
            @keyup.enter="addEntries" 
            v-model="newEntries"
        />

        <button 
            class="add-entry__btn"
            @click="addEntries">Add</button>

    </div>
</template>

<script>

export default {
    name: 'add-entry',
    props: ['entries'],
    data: function() {
        return {
            addEntryIsOpen: false,
            newEntries: ''
        }
    },
    methods: {
        addEntries: function() {
            this.entries.push({name:this.newEntries});
            this.newEntries = '';
        }
    }
}

</script>

还有我的list-entries.vue组件

<template>
    <div class="container-flex">
        <div class="wrapper">

            <div class="entries">

                <div class="entries__header">

                    <div class="entries__header__title">
                        <p>Competition Entries</p>
                    </div>

                    <div class="entries__header__search">
                        <input 
                            type="text" 
                            name="Search" 
                            class="input input--search" 
                            placeholder="Search..." 
                            v-model="search">
                    </div>
                </div>

                <div class="entries__content">
                    <ul class="entries__content__list">
                        <li v-for="entry in filteredEntries">
                            {{ entry.name }} 
                        </li>
                    </ul>
                </div>

                <add-entry :entries.sync="entries"/>

            </div>

        </div>
    </div>
</template>

<script>

import addEntry from '@/components/add-entry.vue'
import pickWinner from '@/components/pick-winner.vue'

export default {
    name: 'entry-list',
    components: {
        addEntry,
        pickWinner
    },
    data: function() {
        return {
            search: '',
            entries: [
                {
                    name: 'Geoff'
                },
                {
                    name: 'Stu'
                },
                {
                    name: 'Craig'
                },
                {
                    name: 'Mark'
                },
                {
                    name: 'Zoe'
                }
            ]
        }
    },
    computed: {
        filteredEntries() {
            if(this.search === '') return this.entries
            return this.entries.filter(entry => {
                return entry.name.toLowerCase().includes(this.search.toLowerCase())
            })   
        }
    }
}

</script>