首页 > 其他分享 >vue3 实现自定义 v-model

vue3 实现自定义 v-model

时间:2022-12-02 16:44:31浏览次数:41  
标签:vue const 自定义 value vue3 model modelValue emit

在 vue 中,form 表单输入可以通过 v-model 实现双向数据绑定,例如: <input v-model="text" /> {{text}}
在表单中输入时,页面展示的 data-text 也会相应改变
如果是封装的通用输入表单,一般会使用 prop+emit 来实现父子组件数据传递 如:封装一个数字输入框 子组件: child.vue

<template>
<input :value="modelValue" @input="inputValue" type="number" />
</template>

<script>
export default {
  props: {
    modelValue: {
      type: String,
      default: "",
    },
  },
  setup(props, { emit }) {
    const inputValue = (e) => {
      const value = e.target.value;
      emit("updatemodelValue", value);
    };
    return {
      inputValue,
    };
  },
};
</script>
父组件: parent.vue
<template>
  <div>
    <number-input
      :modelValue="modelValue"
      @updateModelValue="updateModelValue"
    />
    <div>modelValue: {{ modelValue }}</div>
  </div>
</template>

<script>
import { reactive, toRefs } from "vue";
import NumberInput from "../components/child.vue";
export default {
  components: {
    NumberInput,
  },
  setup() {
    const value = reactive({
      modelValue: "",
    });

    const updateModelValue = (val) => {
      value.modelValue = val;
    };
    return {
      updateModelValue,
      ...toRefs(value),
    };
  },
};
</script>

这样实现父子数据的双向传递,那可不可以直接在使用子组件时用 v-model 实现这些效果呢?vue3 提供了 v-model 的自定义事件支持.直接看实现步骤 子组件: child2.vue
<template>
  <div>
    name: <input :value="modelValue" @input="inputValue" type="number" /> title:
    <input :value="titleValue" @input="inputTilte" />
  </div>
</template>

<script>
export default {
  props: {
    modelValue: {
      type: String,
      default: "",
    },
    titleValue: {
      type: String,
      default: "",
    },
  },
  setup(props, { emit }) {
    const inputValue = (e) => {
      const value = e.target.value;
      emit("update:modelValue", value);
    };
    const inputTilte = (e) => {
      emit("update:titleValue", e.target.value);
    };
    return {
      inputValue,
      inputTilte,
    };
  },
};
</script>
父组件: parent.vue
<template>
  <div>
    <h3>v-model实现</h3>
    <my-input v-model="inputValue" v-model:titleValue="title" />
    <div>inputValue: {{ inputValue }}</div>
    <div>titleValue: {{ title }}</div>
  </div>
</template>

<script>
import { reactive, toRefs } from "vue";
import MyInput from "../components/child2.vue";
export default {
  components: {
    MyInput,
  },
  setup() {
    const value = reactive({
      inputValue: "",
      title: "",
    });

    return {
      ...toRefs(value),
    };
  },
};
</script>
v-model 可以有多个,默认的名称是 modelValue 与 update:titleValue 如果是其他名字,在 v-model 后面加上名称的后缀 v-model:titleValue + update:titleValue
这样写帮我们省去了父组件中 emit 的接收事件,vue 帮我们声明了这个事件

标签:vue,const,自定义,value,vue3,model,modelValue,emit
From: https://www.cnblogs.com/steamed-twisted-roll/p/16944887.html

相关文章