浅谈 vue 3 组件间的 v-model 指令

247 阅读1分钟

前言

v-model 可能大多数都是在表单输入里用,普通的表单传值和获取一般是这样:

<input :value="text" @input="event => text = event.target.value">

v-model帮我们简化了这些步骤:

<input v-model="text">

可以添加 .lazy, .number,.trim 对表单输入的内容做不同的操作。

然而随着项目里功能的构建,组件化是必不可少的一个操作,不仅能灵活业务模块,还能提高代码复用率,打造高内聚低耦合优质项目。

那么我们就来简单捋一捋组件之间的双向数据绑定。

用法

1. 选项式 api 使用

父组件

<SimpleDemo v-model="bar" /> 

子组件

<a-input type="text" :value="modelValue" @input="onSearchInput" />

props:{
  modelValue:{
   type:String
  }
}
methods: {
  onSearchInput(event: Event): void {
       this.$emit("update:modelValue",event.target.value);
     }
  }
2. 使用 computed property 的功能来定义 getter 和 setter。

父组件

<SimpleDemo v-model="bar" />

子组件

<a-input type="text" class="demo-input" v-model:value="barValue" />

props:{
  modelValue:{
   type:String
  }
}
computed:{
  barValue: {
   get(): string {
      return this.modelValue;
   },
   set(v: string): void {
    this.$emit("update:modelValue", v);
   }
  }
}
3. v-model 参数:默认情况下,组件上的 v-model 使用 modelValue 作为 prop 和 update:modelValue 作为事件。我们可以通过向 v-model 传递参数来修改这些名称:

选项式api:

父组件

<SimpleDemo v-model:foo="bar" />

子组件

<a-input type="text" class="demo-input" v-model:value="barValue" />

props:{
  foo:{
   type:String
  }
}
computed:{
  barValue: {
   get(): string {
      return this.foo;
   },
   set(v: string): void {
    this.$emit("update:foo", v);
   }
  }
}
4. 在 选项式 setup时使用

父组件

  <SimpleDemo v-model="bar" />

子组件

<a-input  type="text" :value="modelValue" @input="onSearchInput" />

props:{
   modelValue:{
   type:String
   }
}
setup(props, { emit }) {
  const onSearchInput = (event: Event) => {
    emit("update:modelValue", event.target.value);
  };
  return {
   onSearchInput
  };
}
5. 在组合式单文件组件时

父组件

<SimpleDemo v-model:visible="isVisible" />

子组件

<script lang="ts" setup>

const componentsProps = withDefaults(
  defineProps<{
    visible: boolean;
  }>(),
  {
    visible: false
  }
);

const componentEmits = defineEmits<{
  (event: 'update:visible', visible: boolean): void
}>()

</script>
写在结尾

在vue3里还增加了能在单个组件实例上创建多个 v-model 双向绑定功能,其本质上来讲和单个v-model时没有太大区别,没增加一个双向绑定就多一个props。同样组件的 v-model 也支持自定义的修饰符,但不是介绍重点就不举例了,有兴趣的朋友可以自行了解一下。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情