我必须在vue2中创建动态形式。我想将动态字段的值保存在命名对象中,以便我可以在提交时传递它们。以下代码正常工作,除了我第一次更改输入值时会在控制台中出现错误(虽然将正确传播值):
[TypeError: Cannot read property '_withTask' of undefined]
这是我定义道具的方式:
props: {
fields: {
type: Object,
default: {startWord: 'abc'}
},
},
这就是我从输入字段填充模型的方式:
v-model="fields[field.id]"
这是整个代码:
<template>
<div>
<!-- Render dynamic form -->
<div v-for="(field, key) in actionStore.currentAction.manifest.input.fields">
<!-- Text -->
<template v-if="field.type == 'string'">
<label>
<span>{{key}} {{field.label}}</span>
<input type="text" v-bind:placeholder="field.placeholder"
v-model="fields[field.id]"/>
</label>
</template>
<!-- Footer -->
<footer class="buttons">
<button uxp-variant="cta" v-on:click="done">Done</button>
</footer>
</div>
</template>
<script>
const Vue = require("vue").default;
const {Bus, Notifications} = require('../../Bus.js');
module.exports = {
props: {
fields: {
type: Object,
default: {startWord: 'abc'}
},
},
computed: {
actionStore() {
return this.$store.state.action;
},
},
methods: {
done() {
console.log('fields', this.fields);
Bus.$emit(Notifications.ACTION_INPUT_DONE, {input: this.fields});
}
},
}
</script>
再次,一切正常工作(在输入中显示初始值,将新值传播到模型等)。但是,当我第一次输入新字符时,我会遇到此" _withTask"错误(实际上仅在第一个按键上)。在该初始错误之后,它不会再次弹出。
- 附录 -
这就是清单/字段的样子:
manifest.input = {
fields: [
{ id: 'startWord', type: 'string', label: 'Start word', placeholder: 'Enter start word here...' },
{ id: 'startWordDummy', type: 'string', label: 'Start word dummy', placeholder: 'Enter start word here...' },
{ id: 'wordCount', type: 'integer', label: 'Word count' },
{ id: 'clean', type: 'checkbox', label: 'Clean up before' },
]
}
- 更新 -
我刚刚发现,如果我最初设置了具有静态值的动态字段值,我不会收到这些字段的错误:
created() {
this.fields.startWord = 'abc1';
},
这不是一个选项,因为它将是一个动态的字段列表。那么处理这样的方案的最佳方法是什么?
来自文档:由于现代javascript的局限性(以及对object.observe的放弃),Vue无法检测属性添加或删除。由于Vue在实例初始化过程中执行了Getter/Setter转换过程,因此必须在数据对象中存在属性,以使VUE转换并使其反应性。
我知道这是不好的主意,创建了V-Model的对象键。我在html中要做什么:
<input type="text"
:placeholder="field.placeholder"
@input="inputHandler(event, field.id)" />
然后在JS中:
methods: {
// ...
inputHandler({ target }, field) {
this.fields[field] = target.value;
}
},