Vue3中的v-model

9,576 阅读1分钟

Vue3中的v-model对比Vue2中的v-model发生了很大的变化,变化如下:

  • 变更:在自定义组件上使用v-model时,属性及事件的默认名称变了
  • 变更:v-bind.sync修饰符在Vue3中被去掉了,合并到了v-model
  • 新增: 同一组件可以同时设置多个v-model
  • 新增:开发者可以自定义v-model修饰符

Vue2的语法

在Vue2中,在组件上使用v-model相当于传递了value属性,触发了input事件

<Child v-model="msg"/>
//以上写法相当于:  
<Child :value="msg" @input="msg=$event"/>

如果想要改变prop或者事件名称,则在Child中添model选项

// 父组件
<Child v-model="msg"/>
//子组件Child.vue
export default {
  model: {
    prop: 'title',
    event: 'change'
  }
}

所以,这个例子中的v-model是以下的简写

<Child :title="msg" @change="msg=$event"/>

某些情况下,我们需要对prop进行双向绑定,以弹框组件为例,父组件可以定义弹框是否为visible,并通过prop的方式传递给子组件,子组件也可以控制visible是否隐藏,并将visible的值传递给父组件。可以通过以下方式将visible的值传递给父组件:

  this.$emit('update:visible',false)

然后在父组件中监听这个事件进行数据更新:

 <Dialog :visible="isVisible" @update:visible="isVisible=$event"/>

以上代码可以使用v-bind.sync来简化:

  <Dialog :visible.sync="isVisible"/>

Vue3的语法

在Vue3中,自定义组件上使用v-model,相当于传递一个modelValue属性,同时触发update:modelValue事件

<Child v-model="isVisible">  
// 相当于
<Child :modelValue="isVisible" @update:modelValue="isVisible=$event">

我们还可以绑定多个v-model

<Child v-model:visible="isVisible" v-model:content="content"/>
//以上代码相当于:
<Child :visible="isVisible" :content="content" @update:visible="isVisible" @update:content="content"/>

这里贴一个完整的例子:

//App.vue
<template>

<!-- <Child v-model="state.name" v-model:age="state.age" /> -->
   //等价以下:
  <Child
   :modelValue="state.name"
   @update:modelValue="state.name = $event"
   :age="state.age"
   @update:age="state.age = $event"
  />
</template>

<script>

import { defineComponent, reactive, reeactive } from "vue";
import Child from "./components/Child.vue";
export default defineComponent({
  components: {
     Child,
   },
  setup() {
   const state = reactive({
   name: "Jerry",
   age: 20,
   });
 return { state };
  },
});
</script>
//Child.vue
<template>
   <span @click="changeInfo">我叫{{ modelValue }},今年{{ age }}岁</span>
</template>

<script>

import { defineComponent } from "vue";
export default defineComponent({
  props: ["modelValue", "age"],
  setup(props, context) {
  const changeInfo = () => {
    context.emit("update:modelValue", "Tom");
    context.emit("update:age", 30);
  };
    return { changeInfo };
  },
});
</script>

参考

Vue3.0 新特性以及使用经验总结
Vue3.2 setup语法糖、Composition API归纳总结
Vue3文档