组件内的 2 种数据绑定组件

2 Way Databind components within Components

我正在努力重用我的组件。

我想将传递到我的组件的数据作为 prop 传递到另一个组件。
如果我这样做,vue 会抱怨道具发生变化。

示例: 我想在我的应用程序的多个位置显示联系人。
为此,我创建了一个联系人组件以重用它:

<template>
    <div>
        <input :value="contact.firstName" @input="$emit('update:contact', {...contact, firstName: $event.target.value})">
        <Mother v-model:mother="contact.mother"/>
    </div>
</template>

<script>
import Mother from '@/components/Mother'

export default {
  name: 'Contact',
  components: {
    Mother
  },
  props: {
    contact: Object,
  },
  emit: ['update:contact'],
  methods: {
  }
}
</script>

每个联系人都有一个妈妈,妈妈不仅仅在联系人组件中显示在其他地方。 这就是为什么我创建了一个母组件,供联系人使用。

<template>
    <div>
        <input :value="mother.lastName" @input="$emit('update:mother', {...mother, lastName: $event.target.value})">
    </div>
</template>

<script>
export default {
  name: 'Mother',
  props: {
    mother: Object,
  },
  emit: ['update:mother'],
  methods: {
  }
}
</script>

现在我希望能够同时改变联系人和母亲,并且我希望能够在同一个站点上使用两个联系人组件。

如果我按照说明的方式使用它,我会收到此错误:

 ERROR  Failed to compile with 1 error                                  09:17:25

 error  in ./src/components/Contact.vue

Module Error (from ./node_modules/eslint-loader/index.js):

/tmp/vue-example/src/components/Contact.vue
  4:27  error  Unexpected mutation of "contact" prop  vue/no-mutating-props

✖ 1 problem (1 error, 0 warnings)

我有一个示例项目显示了我的问题: https://gitlab.com/FirstWithThisName/vue-example.git

感谢您的帮助

取决于您的应用程序的复杂程度。 一种选择是双向数据绑定,如下所述: https://v3.vuejs.org/guide/component-basics.html#using-v-model-on-components

所以你基本上 emit 对父级的更改。

对于更复杂的应用程序,我不会将在多个组件中使用的数据作为道具传递,而是使用商店。一个简单的反应对象; provide/inject or use something like Vuex.

首先我需要假设几点。

  • 您想使用 v-model。
  • 您希望链接组件。

Vue SFC 游乐场上的工作示例 here
*请注意,示例站点上的导入路径不同。

App.vue

<template>
    <Contact v-model="contact" />
    {{ contact }}
</template>
... remaining code omitted 

Contact.vue

<template>
    <div>
        <input v-model="localValue"/>
        <Mother v-model="childValue" />
    </div>
</template>

<script>
import Mother from "./Mother.vue"
export default {
    name: "Contact",
    components: {
        Mother
    },
    props: {
        modelValue: Object,
    },
    mounted(){
        this.childValue = this.modelValue.mother
    },
    data: () => ({
        localValue: "",
        childValue: null
    }),
    watch:{
        updatedData(){
            this.$emit('update:modelValue', this.updatedData)
        }
    },
    computed: {
        updatedData() {
            return { firstName: this.localValue, mother: this.childValue };
        },
    },
};
</script>

Mother.vue

<template>
    <div>
        <input
            v-model="localValue"
            @input="$emit('update:modelValue', updatedData)"
        />
    </div>
</template>

<script>
export default {
    name: "Mother",
    props: {
        modelValue: Object,
    },
    data: () => ({
        localValue: "",
    }),
    computed: {
        updatedData() {
            return { ...this.modelValue, lastName: this.localValue };
        },
    },
};
</script>

您可能知道,props 无法更改,因此您需要“复制”每个组件上的值以在本地处理。

如果 Mother 组件永远不会单独使用,v-model 可以拆分为 v-onv-bind

最后,关于推荐,如果数据开始增长或深度级别增加,像这样的链接会变得非常混乱。您可以制作另一个 Wrapper 组件,其中包含 ContactMother 组件,而不是水平缩放。