【发布时间】:2021-03-16 16:02:28
【问题描述】:
我有一个小问题,我创建了一个包来管理表单,一切正常,直到我需要基于 API 响应创建一个动态表单。
这是包裹:https://github.com/nulvem/js-form
可以用npm安装:
npm install @nulvem/js-form
这是我调用 Form 类的 Vue 组件:
<script>
import {Form} from '@nulvem/js-form'
export default {
data() {
return {
form: new Form({
template: {
value: null,
validation: {
rules: 'required',
messages: {
required: 'You must select the type of report'
}
}
}
})
}
},
mounted() {
this.form.template = 'random-id'
// These data will be obtained from an API
let fields = [
'start_date',
'end_date',
'wallets',
]
fields.forEach((field) => {
let fieldData = {
value: null,
validation: {
rules: 'required',
messages: {
required: `You must enter the field ${field.description}`
}
}
}
this.form.$addField(field, fieldData)
})
// Here we can only see the getter/setter of the template property that was passed when instantiating the Form class
console.log(this.form)
}
}
</script>
问题是:我在创建 new Form ({...}) 实例期间传递给表单的字段是反应性的,因为当我通过调用 this.form.$AddField() 函数添加新字段时,这些字段没有反应性。
有趣的是Form类的construct调用了一个名为this.form.$AddFields()的函数,该函数多次调用this.form.$AddField()函数。
为什么它在构造函数中起作用而在分开调用时不起作用?如何解决这个问题?
知道会发生什么吗?这让我发疯了,我一直试图找到问题几个小时,但我找不到它。
编辑
作为快速修复,我们在包中进行了更改,可以将 Form 实例作为第三个参数传递给 $addFields 函数,因此属性是反应性的,但是我们希望它在没有的情况下工作必须传递这个参数。
【问题讨论】:
-
Vue 2 不会检测到对象属性的添加/删除,因此您必须为此使用
Vue.set()/Vue.delete()。如果您仅使用 API 中的所有字段初始化mounted()中的表单,那么一旦您拥有所有可用字段,我将在mounted()中设置form = new Form()。那么你就不需要传递上下文了。 -
您必须将
form实例替换为包含字段的新实例。我认为最简单的方法是在data: () => { form: null }中放置一个null占位符,并在您拥有API 中的所有字段时设置表单类实例。 Vue 反应性的意思是:所有属性都替换为 getter/setter,但这仅发生在顶层,而不是针对每个单独的嵌套 prop。除非您替换form,否则 Vue 不会知道更改。而Vue.set()正是这样做的。它替换了道具中的实例。
标签: javascript typescript vue.js