我正在尝试构建一个可重用的组件来处理使用 Vue.js 通过 AJAX 提交表单。理想情况下,我想要做的是有一个通用组件,可以用来代替 HTML form
元素,其中可能包含一组未知的表单元素,例如 input
, select
, textarea
等等。
我的组件有以下代码,名为 ajax-form
:
<template>
<form class="form" :action="action" :method="method" v-on:submit.prevent="ajaxSubmit">
<slot></slot>
</form>
</template>
<script>
module.exports = {
props: {
action: {
required: true,
type: String
},
method: {
default: 'post',
required: false,
type: String
}
},
data() {
return {
formData: {}
}
},
methods: {
ajaxSubmit() {
// Do ajax
}
}
}
</script>
在我的 HTML 中,我会有如下内容:
<ajax-form action="http://example.com/do/something">
<input name="first_name" type="text">
<textarea name="about_you"></textarea>
</ajax-form>
我最希望发生的事情是使用它的插槽将所有放置在我的组件内的表单元素映射到我的 Vue 组件实例中的 data.formData
属性。所以在这种情况下, data
属性看起来像:
data: {
formData: {
first_name: '',
about: ''
}
}
如果我要在我的 HTML 中向组件添加另一个字段,我希望它也能映射到 Vue 实例的 data
属性。
有什么办法可以做到这一点?有没有一种方法可以告诉 Vue,当我通过插槽将表单元素放入组件时,我希望将此元素映射到组件的 data
中的某些内容?
我尝试在每个表单元素上添加 v-model
和 v-bind
以查看它是否会以某种方式将数据传递到组件的数据中:
<ajax-form action="http://example.com/do/something">
<input name="first_name" type="text" v-model="formData.first_name">
</ajax-form>
但是,Vue 抱怨反应式数据属性必须在模板中使用之前声明:
[Vue 警告]:属性或方法“formData”未在实例上定义,但在渲染期间被引用。确保在数据选项中声明响应式数据属性。
原文由 Jonathon 发布,翻译遵循 CC BY-SA 4.0 许可协议
你不能做你要求的事情,因为插槽范围仅限于父范围。
您可以在全局 Vue 实例上定义 formData,因此现在可以从父范围访问它。
现在你可以将它作为 prop 传递给表单: