javascript - Vue 将插槽数据存储在父组件中
问题描述
我正在构建一个使用插槽接收多个输入字段的组件,当用户提交父组件内的表单时,我想输出所有输入的值。
索引.html
<filter-form>
<input type="text" name="email" :value="form.email" />
</filter-form>
FilterForm.vue
<template>
<div>
<form
@submit.prevent="onSubmit"
>
<slot />
<div>
<button>
Submit
</button>
</div>
</form>
</div>
</template>
<script>
export default {
data () {
return {
form: {
email: 'test@email.com'
}
}
}
}
</script>
如您所见,我在 index.html 中引用了“form.email”,它应该使用 FilterForm 组件中的数据填充输入,但这会引发此错误
Property or method "form" is not defined on the instance but referenced during render
这是有道理的,因为 index.html 文件中没有表单数据。
如何使用这个系统,以便表单的数据保存在 FilterForm 组件中,但我可以将任意数量的表单输入添加到 index.html 文件中。
解决方案
正如@User 28 所提到的,您可以利用槽和作用域槽来使其与任意数量的字段一起使用,如下所示:
<template>
<div id="app">
<FormWrapper :names="['name', 'country']" @submit="process($event)">
<template #default="{ form }">
<input name="name" type="text" v-model="form.name">
<input name="country" type="text" v-model="form.country">
</template>
</FormWrapper>
</div>
</template>
<script>
import FormWrapper from "./components/FormWrapper";
export default {
name: "App",
components: {
FormWrapper
},
methods: {
process(values) {
console.log(values);
}
}
};
</script>
在这里,FormWrapper
可以嵌套任意输入字段。一些关键点:
- 您需要为
names
您关心的字段提供一些唯一 ID 的道具。 - 当
FormWrapper
提交内部表单时,submit
将触发一个事件,并将值作为对象发送。 - 另请注意,我们为
form
对象中的插槽传递数据,并将其绑定到我们的输入v-model
。
这是FormWrapper
组件:
<template>
<div class="form-wrapper">
<slot :form="form"></slot>
<div class="controls">
<button @click="submit()">Submit</button>
</div>
</div>
</template>
<script>
export default {
props: {
names: Array
},
data() {
return {
form: {}
};
},
created() {
for (const name of this.names) {
this.$set(this.form, name, "");
}
},
methods: {
submit() {
this.$emit("submit", this.form);
}
}
};
</script>
您可以查看https://codesandbox.io/s/so-form-wrapper-yxz0i以获取工作示例。