自定义表单组件实现v-model双向绑定

159 阅读1分钟

自定义的表单组件,也需要有v-model用着才方便。 实现思路很简单,无非是在子组件的value更新时,同步更新父组件传过来的v-model。

我们可以在el-select的change事件中调用$emit来实现。 也可以使用computed的get和set来处理。下方的代码使用computed。

需要注意的是,父组件使用v-model传递给子组件的prop默认是value,事件默认为input。

我们直接写props:{value},$emit('input',...)即可。但如果我们想用别的属性名呢?

vue关于#model的说明

  • 类型{ prop?: string, event?: string }

  • 详细

    允许一个自定义组件在使用 v-model 时定制 prop 和 event。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突。

最后上我实现的代码

<template>
  <el-select
    v-model="value"
    filterable
    remote
    reserve-keyword
    :placeholder="placeholder"
    :remote-method="remoteMethod"
    :loading="loading"
    :attr="$attr"
  >
    <el-option
      v-for="item in options"
      :key="item[props.value]"
      :label="item[props.label]"
      :value="item[props.value]"
    />
  </el-select>
</template>
<script>
export default {
  name: 'RemoteSelect',
  props: {
    modelValue: { type: [Number, String, Array] },
    placeholder: { type: String, default: '请输入关键词' },
    // 配置options的key,vaule,label
    props: {
      type: Object,
      default: () => {
        return { key: 'value', value: 'value', label: 'label' }
      }
    },
    searchMethod: {
      type: Function
    }
  },
  model: {
    prop: 'modelValue',
    event: 'change'
  },

  data() {
    return {
      loading: false,
      options: null
    }
  },
  computed: {
    value: {
      get() {
        return this.modelValue
      },
      set(val) {
        this.$emit('change', val)
      }
    }
  },

  methods: {
    async remoteMethod(query) {
      this.options = await this.searchMethod(query)
    }
  }
}
</script>