当prop具有get()和set()时,与:model.sync进行两种数据绑定

时间:2018-10-25 17:09:11

标签: vue.js vuex

我有一个计算所得的属性,可用作输入上的v-model。我以这种方式编写它来获得反应性-这调用了我的setText Vuex动作,然后我可以通过我的吸气剂text获得它。看起来像这样:

text: {
   get() {
     return this.text;
   },
   set(value) {
     this.setText(value);
   },
 },

像这样在我的输入中使用它:

<input class="input" type="text" v-model="text" />

这很好。现在,我将有问题的input放入我使用的单独组件中。这意味着我必须通过text v模型作为道具,这与:model.sync一样,就像这样:

<myInput :model.sync="text"/>

myInput组件中,我使用如下道具:

<input class="input" id="search-order" type="text" :value="model" @input="$emit('update:model', $event)">

但是,这似乎根本不起作用,每当我在输入中键入内容时,输入内容就会显示:[object InputEvent],如果我尝试查看且model的值是{{1} }。我假设这是因为我在自己的计算属性上有getter和setter方法。如何将这些信息传递给子组件?

1 个答案:

答案 0 :(得分:0)

您可以在自定义组件中支持.sync指令,而不使用v-model修饰符。 v-modelvalue道具和input事件的语法糖。

要支持v-model,只需确保您的自定义组件具有一个value属性,并发出一个具有新值input的{​​{1}}事件。

这是我使用的this.$emit('input', event.target.value)组件的示例,它是用TypeScript编写的:

<BaseInput>

您可以像这样使用它:

<template>
  <input
    :type="type"
    :value="value"
    class="input"
    v-on="listeners"
  >
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  name: 'BaseInput',

  props: {
    type: {
      type: String,
      default: 'text',
    },

    value: {
      type: [String, Number],
      default: '',
    },

    lazy: {
      type: Boolean,
      default: false,
    },

    number: {
      type: Boolean,
      default: false,
    },

    trim: {
      type: Boolean,
      default: false,
    },
  },

  computed: {
    modelEvent(): string {
      return this.lazy ? 'change' : 'input'
    },

    parseModel(): (value: string) => string | number {
      return (value: string) => {
        if (this.type === 'number' || this.number) {
          const res = Number.parseFloat(value)
          // If the value cannot be parsed with parseFloat(),
          // then the original value is returned.
          return Number.isNaN(res) ? value : res
        } else if (this.trim) {
          return value.trim()
        }
        return value
      }
    },

    listeners(): Record<string, Function | Function[]> {
      return {
        ...this.$listeners,
        [this.modelEvent]: (event: HTMLElementEvent<HTMLInputElement>) =>
          this.$emit(this.modelEvent, this.parseModel(event.target.value)),
      }
  },
})
</script>