在 vue 中以编程方式更新多个输入
Posted
技术标签:
【中文标题】在 vue 中以编程方式更新多个输入【英文标题】:Update multiple inputs programmatically in vue 【发布时间】:2020-07-14 00:43:23 【问题描述】:我有一个表单,当另一个字段被更新时,我需要更新多个其他表单字段。例如,我有一个联系人姓名,根据联系人姓名,我需要更新电子邮件和电话的值。
<template>
<custom-input :value="contact.name" @input="event => contact.name = event.target.value" />
<custom-input :value="contact.phone" @input="event => contact.phone = event.target.value" />
<custom-input :value="contact.email" @input="event => contact.email = event.target.value" />
</template>
<script>
...
props:
contact:
type: Object,
required: true
,
watch:
"contact.name": function(value)
if (this.contact.name === "john")
this.contact.email = "john@email.com"
this.contact.phone = "1111111111"
else if (this.contact.name === "ed")
this.contact.email = "ed@email.com"
this.contact.phone = "2222222222"
...
</script>
我知道 Vue 不喜欢这样,因为它将 DOM 与数据模型分开。我的第一个想法是使用$refs
,但这些都是只读的。这样做的正确方法是什么?
我的另一个想法是将name
和phone
的值设置为计算属性。这样做的问题是它不会在父组件的表单上得到监视。
这也可能与我对“双向”绑定的误解有关。我一直认为表单是一种方式,而组件脚本中的数据是另一种方式,而事实并非如此。那么,还有什么办法呢?
我的最后一个想法是我可能不得不发出一个事件?
<template>
<custom-input :value="contact.name" @input="event => contact.name = event.target.value" />
<custom-input ref="phone" :value="contact.phone" @input="event => contact.phone = event.target.value" />
<custom-input ref="email" :value="contact.email" @input="event => contact.email = event.target.value" />
</template>
<script>
...
props:
contact:
type: Object,
required: true
,
watch:
"contact.name": function(value)
if (this.contact.name === "john")
this.$refs.email.$emit("input", "john@email.com")
this.$refs.phone.$emit("input", "111111111111")
else if (this.contact.name === "ed")
this.$refs.email.$emit("input", "ed@email.com")
this.$refs.phone.$emit("input", "222222222222")
这似乎也不起作用。真可惜。
编辑
修正语法错误
编辑 2
表明input
实际上是一个单独的子组件
【问题讨论】:
除了:value
和@input
的不必要分离(只使用v-model
),我认为您在这里所做的没有任何问题。也许我误解了你的问题?
@DecadeMoon 可悲的是它不起作用。应该吗?
没关系,我重新阅读了您的代码并发现了一些语法错误。看我的回答。
您所做的那些编辑清除了一切,谢谢。我仍然认为v-model
可以(并且应该)在这里使用,但是由于我们正在处理自定义组件,您可能不会收到它发出的input
事件的本机事件对象。你能确认一下吗?
@DecadeMoon 我怎么知道何时收到该事件?我知道它是基于 Vue 控制台触发的,但它会为 Error in v-on handler: "TypeError: Cannot read property 'value' of undefined"
引发错误
【参考方案1】:
我刚刚注意到您正在尝试修改 Vue 禁止的 props
的值。所有子组件都不能修改从父组件传来的props
中的数据,因为这会使数据流更难理解。您可以在官方网站上阅读更多相关信息:https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow
这就是为什么 Vue 也有 data
是可以被组件修改的本地私有内存。
所以要解决你的问题,你需要在子组件挂载时将props
中的数据复制到data
,并改为修改data
的值。
这是更新后的代码示例(Codepen 也已更新),完全符合您的要求。
模板:
<div id="app">
<div>
<my-form :contact="contact"></my-form>
</div>
</div>
Vue.component('my-form',
data()
return name: '', phone: '', email: ''
,
props:
contact: type: Object, required: true
,
mounted()
this.name = this.contact.name;
this.phone = this.contact.phone;
this.email = this.contact.email;
,
template: `
<div>
<input v-model="name" />
<input v-model="phone"/>
<input v-model="email"/>
<p>
value of input: JSON.stringify( name, phone, email )
</p>
</div>
`,
watch:
name(value)
if(value === 'john')
this.phone = '123456';
this.email = 'test@gmail.com';
);
new Vue(
el: '#app',
data()
return contact: name: 'initial name', phone: '123456', email: 'initial.email@gmail.com'
)
还有我更新的代码笔:https://codepen.io/aptarmy/pen/PoqgpNJ
【讨论】:
太棒了!让我尝试实现这一点。 @user3162553 我已经测试过了,它可以工作。请告诉我它是否适合你。 它确实有效,但在预选状态时我无法更改电话或电子邮件值。这应该是默认值。不过我忘了提,所以无论如何我都会赞成。 @user3162553 我刚刚更新了答案中的代码示例,使phone
和email
可更新。我的 Codepen 也更新了,请查看。
@user3162553 我的代码已更新。我更新的答案中解释了您的代码不起作用的问题原因。这是因为您试图修改 Vue 不允许的 props
的值。通过props
传输的数据是单向绑定。请重新阅读我的答案,查看更新后的 Codepen,更新您的代码,并告诉我它现在是否有效。以上是关于在 vue 中以编程方式更新多个输入的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Nativescript-vue 中以编程方式折叠 raddataform“组”