如何使用v模型为输入Vue组件设置初始值

时间:2018-08-31 08:01:09

标签: vue.js

我有以下内容:

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>

并在输入中显示该内容。

我想我可以通过简单地将电子邮件设置为data.this中的值来做到这一点,但这没有帮助。我该怎么办?

1 个答案:

答案 0 :(得分:0)

有一个value prop,但您根本没有使用它!因此,您传给value prop的哪个值并不重要:它不会被使用。

我认为您要实现的目标是公开与input组件公开的API类似的API。可以做到的,就是detailed in the docs

Vue处理v-model绑定的作用是假设组件将发出一个input事件,并将新值传递为$event。它还会将value prop的值传递给组件。因此,只要您定义value prop并发出input事件,Vue就会自动处理这种双向绑定。

问题是您的组件充当基础input组件的中间件,但它传递的是不同的绑定而不是转发。

将此内容转换为组件,您不应使用v-model向下传递emailinput组件,而应使用:value@input绑定的组合:您将value组件的prop email-input传递到value组件的prop input并作为{{1} 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事件。

这是解决此问题的关键:旧的实现迫使我们有2个不同的变量:一个变量使父组件可以传递一个值,而另一个input可以修改以存储所选择的建议。

如果我们只是将选择的建议作为常规更改发出,那么我们可以摆脱email-input变量,而只需进行一次绑定。


建议与问题完全无关:您可以直接在email中使用去抖动,而不用替换methods钩子上的方法:

mounted

Lodash将负责将基础功能的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 = ''; }, } });绑定到称为去抖动功能的同一this上。