vue.js - 如何使用 v-model 为输入 Vue 组件设置初始值
问题描述
我有以下组件:
Vue.component('email-input', {
template: '#tmpl-email-input',
name: 'email-input',
delimiters: ['((', '))'],
props: ['name', 'required', 'value'],
data: () => ({
suggestedEmail: '',
email: '',
}),
methods: {
onInput() {
this.checkEmail();
this.$emit('input', this.email);
},
checkEmail() {
Mailcheck.run({
email: this.email,
suggested: suggestion => {
this.suggestedEmail = suggestion.full;
},
empty: () => {
this.suggestedEmail = '';
},
});
},
confirmSuggestion(confirm) {
if (confirm) this.email = this.suggestedEmail;
this.suggestedEmail = '';
},
},
mounted() {
this.checkEmail = _.debounce(this.checkEmail.bind(this), 1000);
},
});
使用这个模板
<template id="tmpl-email-input">
<div>
<input
type="email"
class="form-control"
:name="name || 'email'"
:required="required"
v-on:input="onInput"
v-model="email"
/>
<small class="email-correction-suggestion" v-if="suggestedEmail">
Did you mean ((suggestedEmail))?
<a href="#" class="btn-sm yes" @click.prevent="confirmSuggestion(true)">Yes</a>
<a href="#" class="btn-sm no" @click.prevent="confirmSuggestion(false)">No</a>
</small>
</div>
</template>
<!-- Lodash from GitHub, using rawgit.com -->
<script src="https://cdn.rawgit.com/lodash/lodash/4.17.4/dist/lodash.min.js"></script>
<!-- Mailcheck: https://github.com/mailcheck/mailcheck -->
<script src="/js/lib/mailcheck.js"></script>
<script src="/js/views/partials/email_input.js"></script>
我用它来称呼它
<email-input name="email" required></email-input>
我想为此电子邮件输入设置一个初始值,例如
<email-input name="email" required value="test@test.com"></email-input>
并在输入中显示。
我以为我可以通过简单地将电子邮件设置为数据中的 this.value 来做到这一点,但这无济于事。我怎样才能做到这一点?
解决方案
有一个value
prop
,但你根本没有使用它!因此,您传递的值并不重要value
prop
:它不会被使用。
我认为您想要实现的是公开一个类似于input
组件公开的 API。可以做到这一点,并且在 docs 中有详细说明。
Vue 处理v-model
绑定的做法是假设组件将发出一个input
事件,并将新值作为$event
. 它还将向下传递给组件一个值到value
prop
. 因此,只要您定义 avalue
prop
并发出input
事件,Vue 就会自动处理这种 2-way 绑定。
问题是您的组件充当底层input
组件的中间件,但它传递的是不同的绑定而不是转发它。
将其转换为您的组件,您不应该使用v-model
传递email
给input
组件,而是结合:value
和@input
绑定:您将组件传递value
prop
给email-input
组件value
prop
,并且作为组件的事件input
处理程序,您应该只发出另一个事件与相同的有效载荷。input
input
input
$event
模板:
<template id="tmpl-email-input">
<div>
<input
type="email"
class="form-control"
:name="name || 'email'"
:required="required"
:value="value"
@input="onInput($event.target.value)"
/>
<small class="email-correction-suggestion" v-if="suggestedEmail">
Did you mean ((suggestedEmail))?
<a href="#" class="btn-sm yes" @click.prevent="confirmSuggestion(true)">Yes</a>
<a href="#" class="btn-sm no" @click.prevent="confirmSuggestion(false)">No</a>
</small>
</div>
</template>
<!-- Lodash from GitHub, using rawgit.com -->
<script src="https://cdn.rawgit.com/lodash/lodash/4.17.4/dist/lodash.min.js"></script>
<!-- Mailcheck: https://github.com/mailcheck/mailcheck -->
<script src="/js/lib/mailcheck.js"></script>
<script src="/js/views/partials/email_input.js"></script>
请注意从
@input="onInput"
到的更改,@input="onInput($event.target.value)"
以便我们可以访问onInput
方法中的新值。
零件:
Vue.component('email-input', {
template: '#tmpl-email-input',
name: 'email-input',
delimiters: ['((', '))'],
props: ['name', 'required', 'value'],
data: () => ({
suggestedEmail: ''
}),
methods: {
onInput(newValue) {
this.$emit('input', newValue);
this.checkEmail();
},
checkEmail() {
Mailcheck.run({
email: this.value,
suggested: suggestion => {
this.suggestedEmail = suggestion.full;
},
empty: () => {
this.suggestedEmail = '';
},
});
},
confirmSuggestion(confirm) {
if (confirm) this.$emit('input', this.suggestedEmail);
this.suggestedEmail = '';
},
},
mounted() {
this.checkEmail = _.debounce(this.checkEmail.bind(this), 1000);
},
});
注意方法的变化:现在它接受一个带有新值的参数,并在检查电子邮件地址之前onInput
发出一个input
带有该值的事件。它是按此顺序发出的,以确保我们在检查地址之前已经同步了绑定的值。value
还要注意方法的变化:它只是发出一个事件,confirmSuggestion
而不是更新属性。email
data
input
这是解决这个问题的关键:旧的实现迫使我们有两个不同的变量:一个是父组件可以传递一个值,另一个email-input
可以修改以存储选择的建议。
如果我们只是将选择的建议作为常规更改发出,那么我们可以摆脱email
变量并只使用一个绑定。
建议与问题完全无关:您可以直接使用 debouncemethods
来代替mounted
钩子上的方法:
Vue.component('email-input', {
template: '#tmpl-email-input',
name: 'email-input',
delimiters: ['((', '))'],
props: ['name', 'required', 'value'],
data: () => ({
suggestedEmail: ''
}),
methods: {
onInput(newValue) {
this.$emit('input', newValue);
this.checkEmail();
},
checkEmail: _.debounce(function () {
Mailcheck.run({
email: this.value,
suggested: suggestion => {
this.suggestedEmail = suggestion.full;
},
empty: () => {
this.suggestedEmail = '';
},
});
}, 1000),
confirmSuggestion(confirm) {
if (confirm) this.$emit('input', this.suggestedEmail);
this.suggestedEmail = '';
},
}
});
Lodash 将负责this
将底层函数绑定到this
调用 debounced 函数的函数。
推荐阅读
- google-cloud-functions - 如何从 Google Signin 调试服务器端“redirect_uri_mismatch”错误
- php - 如何删除octobercms中的记录?
- javascript - 为什么我的对象被视为 ql 对象?
- reactjs - 构建反应模块时缩小反应错误#130
- gluon - 如何在 gluon-ts 中使用多个额外的回归器和 DeepAREstimator?
- r - 使用 ggplot 在多个时间序列上移动平均值
- node.js - NodeJS:serialport parser.on()不起作用,无法读取缓冲区
- javascript - 当用户向下滚动时,如何更改徽标并在我的固定标题底部添加彩色边框?
- datetime - 飞镖日期时间坏了?
- angular - 如何发送到模态窗口对象?