组件内的 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-on
和 v-bind
。
最后,关于推荐,如果数据开始增长或深度级别增加,像这样的链接会变得非常混乱。您可以制作另一个 Wrapper
组件,其中包含 Contact
和 Mother
组件,而不是水平缩放。
我正在努力重用我的组件。
我想将传递到我的组件的数据作为 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-on
和 v-bind
。
最后,关于推荐,如果数据开始增长或深度级别增加,像这样的链接会变得非常混乱。您可以制作另一个 Wrapper
组件,其中包含 Contact
和 Mother
组件,而不是水平缩放。