【问题标题】:Vue.js Dynamically Mapping Data Between Parent and Child ComponentVue.js 在父子组件之间动态映射数据
【发布时间】:2021-04-29 06:38:00
【问题描述】:

当我试图在父组件和子组件之间正确映射数据时,我觉得自己将走上一条效率极低的道路。

如果我有一个像下面这样的简单子 Vue 元素

common/InputText.vue

<template>
    <input v-bind:id="name" v-bind:value="value" v-on:input="changed($event, $event.target.value)">
</template>

<script>
    props: ['name', 'value'],
    methods: {
        changed(event, value) { this.$emit('emitChanged', event, value); }
    }
</script>

如果我有一个像下面这样的父 Vue 元素,它将数据绑定到子元素。问题是它似乎只是从父绑定到子,父数据没有更新

Parent.vue

<input-text name="field01" v-bind:value="field01" @emitChanged="changed"></input-text>
<input-text name="field02" v-bind:value="field02" @emitChanged="changed"></input-text>

<script>
    import inputText from "./common/InputText.vue";
    export default {
        data() {
            return() {
                field01: '',
                field02: ''
            }
        },
        components: {
            input-text: inputText
        },
        changed(event, newValue) {
            console.log(newValue);
        }
    }
</script>

通过将changed 方法更改为以下方法,我可以使用 Child 返回的任何数据来更新 Parent 数据

changed(event, newValue) {
    console.log(newValue);
    if( event.target.id == 'field01' ) {
        this.field01 = newValue;
    }
    if( event.target.id == 'field02' ) {
        this.field02 = newValue;
    }
}

虽然这感觉像是一种 hack,但如果有很多输入字段,它就会变得难以管理。重新更新 Parent 数据的正确方法是什么?

【问题讨论】:

  • 这听起来是实施 Vuex 的最佳时机;)
  • 一个基于通量模式的状态管理框架。我强烈建议您了解它,它将帮助您避免许多您发现自己陷入困境的兔子洞vuex.vuejs.org
  • @maxshuty 请解释为什么在解决这个问题时需要vuex
  • @ashwinbande 我从未说过这是必需的解决方案。但是,如果您在管理状态时遇到问题并且没有使用 Vuex,那么可能是时候开始研究它了。当然,它可以添加一些额外的样板,但是一旦你开始将 props 向下传递几层深的组件并使用 Vuex 解决所有这些问题,你就会陷入许多兔子洞。除非应用程序是一个极其微不足道的应用程序或原型,否则使用 Vuex 不仅可以帮助 OP 学习通量模式,还可以帮助从一开始就防止这些问题。
  • 尽管它对这种情况没有帮助,但听到其他选项总是很高兴,谢谢@maxshuty

标签: javascript vue.js data-binding vue-component


【解决方案1】:

这就是v-model 有用的原因,您可以在不使用v-model 的情况下通过以下方式更改代码来解决您的问题。但我建议尝试实现v-model 方式。

<template>
    <input v-bind:id="name" v-bind:value="value" v-on:input="changed($event, $event.target.value)">
</template>

<script>
    props: ['name', 'value'],
    methods: {
        changed(event) { this.$emit('emitChanged', event); }
    }
</script>
<input-text name="field01" v-bind:value="field01" @emitChanged="changed($event, 'field01')"></input-text>
<input-text name="field02" v-bind:value="field02" @emitChanged="changed($event, 'field02'"></input-text>

<script>
    import inputText from "./common/InputText.vue";
    export default {
        data() {
            return() {
                field01: '',
                field02: ''
            }
        },
        components: {
            input-text: inputText
        },
        changed(event, field) {
            this[field] = event.target.value
        }
    }
</script>

【讨论】:

  • 请原谅我的愚蠢,但是field 参数在changed 方法中来自哪里?
  • changed($event, 'field01')
  • @emitChanged="changed($event, 'field01')"input-text
  • 太棒了,是否也可以包含 newValue 字段?我不熟悉在发出事件中手动包含变量的语法
猜你喜欢
  • 2018-02-13
  • 1970-01-01
  • 2018-09-01
  • 2017-03-14
  • 2018-09-04
  • 2020-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多