首先看到v-model,大多数小伙伴都会想到“响应式”、“双向绑定”,v-model 确实是实现了双向绑定数据,用过vue的人都比较熟悉。v-model 是 Vue 内置的指令,vue2和vue3中的v-model使用有点不太一样,那具体是哪里不一样呢?
在Vue2中v-model的使用
vue2的v-model官方使用
1.在组件上使用 v-model
相当于prop中添加 value属性 并触发 input 事件:
父组件
<template> <div> <div>父组件中的---------{{count}}</div> <ChildTpl v-model="count" /> <!-- 等价于 --> <ChildTpl :value="count" @input="value = $event" /> </div> </template> <script> import ChildTpl from '@/components/ChildTpl.vue'; export default { components:{ ChildTpl }, data() { return { count:0, }; } }; </script>
子组件
<template> <div> <span>{{value}}</span> <button @click="changeValue">count+1</button> </div> </template> <script> export default { data() { return { } }, props:{ value:{ default:0, } }, methods: { changeValue(){ this.$emit('input', this.value+1) } } } </script>
2.如果想要更改 prop属性或事件名称,
则需要在 ChildTpl 组件中添加 model 选项:
父组件
<template> <div> <div>父组件中的---------{{ count }}</div> <ChildTpl v-model="count" /> <!-- 等价于 --> <ChildTpl :customParams="count" @change="count = $event" /> </div> </template> <script> import ChildTpl from "@/components/ChildTpl.vue"; export default { components: { ChildTpl, }, data() { return { count: 0, }; }, }; </script>
子组件
<template> <div> <span>{{ customParams }}</span> <button @click="changeValue">count+1</button> </div> </template> <script> export default { data() { return {}; }, model: { prop: "customParams", // 将默认value属性改为customParams event: "change", // 将默认input事件改为change }, props: { customParams: { type: Number, default: 0, }, }, methods: { changeValue() { this.$emit("change", this.customParams + 1); }, }, }; </script>
3.使用.sync修饰符实现v-model
父组件
<template> <div> <div>父组件中的---------{{ count }}</div> <ChildTpl :num.sync="count" /> <!-- 等价于 --> <ChildTpl :num="count" @update:num="count = $event" /> </div> </template> <script> import ChildTpl from "@/components/ChildTpl.vue"; export default { components: { ChildTpl, }, data() { return { count: 0, }; }, }; </script>
子组件
<template> <div> <span>{{ num }}</span> <button @click="changeValue">count+1</button> </div> </template> <script> export default { data() { return {}; }, props: { num: { type: Number, default: 0, }, }, methods: { changeValue() { this.$emit("update:num", this.num + 1); }, }, }; </script>
在Vue3中v-model的使用
vue3的v-model官方使用介绍
1.在组件上使用v-model
相当于在prop添加了modelValue
属性 并接收抛出 update:modelValue
事件:
父组件
<template> <span>父组件中的---------{{ count }}</span> <ChildTpl v-model="count" /> <!-- 等价于 --> <ChildTpl :modelValue="count" @update:modelValue="count = $event" /> </template> <script setup lang="ts"> import { ref } from "vue"; import ChildTpl from "./components/ChildTpl.vue"; const count = ref(0); </script> <style scoped> </style>
子组件
<template> <div> <span>{{ modelValue }}</span> <button @click="changeValue">count+1</button> </div> </template> <script lang="ts" setup> const emits = defineEmits(["update:modelValue"]); const props = defineProps({ modelValue: { type: Number, default: 0, }, }); const changeValue = () => { emits("update:modelValue", props.modelValue + 1); }; </script>
2.给 v-model 指定参数修改默认绑定的参数名
默认情况下,v-model 在组件上都是使用 modelValue 作为 prop,并以 update:modelValue 作为对应的事件。我们可以通过给 v-model 指定一个参数来更改这些名字:
父组件
<template> <span>{{ count }}</span> <ChildTpl v-model:num="count" /> <!-- 等价于 --> <ChildTpl :num="count" @update:num="count = $event" /> </template> <script setup lang="ts"> import { ref } from "vue"; import ChildTpl from "./components/ChildTpl.vue"; const count = ref(0); </script> <style scoped> </style>
子组件
<template> <div> <span>{{ num }}</span> <button @click="changeValue">count+1</button> </div> </template> <script lang="ts" setup> const emits = defineEmits(["update:num"]); const props = defineProps({ num: { type: Number, default: 0, }, }); const changeValue = () => { emits("update:num", props.num + 1); }; </script>
Vue3的v-model多了哪些特性
1.Vue3移除了model选项和sync修饰符实现v-model
2.Vue3支持使用多个v-model
我们可以在单个组件实例上创建多个 v-model 双向绑定
组件上的每一个 v-model 都会同步不同的 prop,而无需额外的选项
父组件
<template> <div> <span>父组件-------first:{{ first }},last:{{ last }}</span> </div> <ChildTpl v-model:first-name="first" v-model:last-name="last" /> <!-- 等价于 --> <ChildTpl :first-name="first" :last-name="last" @update:first-name="first = $event" @update:last-name="last = $event" /> </template> <script setup lang="ts"> import { ref } from "vue"; import ChildTpl from "./components/ChildTpl.vue"; const first = ref("first"); const last = ref("last"); </script> <style scoped></style>
子组件
<template> <div> <input type="text" :value="firstName" @input="$emit('update:firstName', $event.target.value)" /> <input type="text" :value="lastName" @input="$emit('update:lastName', $event.target.value)" /> </div> </template> <script lang="ts" setup> const props = defineProps({ firstName: { type: String, default: "", }, lastName: { type: String, default: "", }, }); </script>
3.自定义v-model修饰符
我们知道了 v-model 有一些内置的修饰符,例如 .trim,.number 和 .lazy。在某些场景下,你可能想要一个自定义组件的 v-model 支持自定义的修饰符,以按需处理绑定值。
比如下面自定义capitalize修饰符实现首字母大写
组件的 v-model 上所添加的修饰符,可以通过 modelModifiers prop 在组件内访问到。在下面的组件中,我们声明了 modelModifiers 这个 prop,有了这个 prop,我们就可以检查 modelModifiers 对象的键,并编写一个处理函数来改变抛出的值。
父组件
<template> <div> <span>父组件-------myText:{{ myText }}</span> </div> <ChildTpl v-model.capitalize="myText" /> </template> <script setup lang="ts"> import { ref } from "vue"; import ChildTpl from "./components/ChildTpl.vue"; const myText = ref("first"); </script> <style scoped></style>
子组件
<template> <div> <input type="text" :value="modelValue" @input="emitValue" /> </div> </template> <script lang="ts" setup> import { onMounted } from "vue"; const emits = defineEmits(["update:modelValue"]); const props = defineProps({ modelValue: { type: String, default: "", }, modelModifiers: { default: () => ({ capitalize: false }),//这里为了满足ts验证默认设为false }, }); onMounted(() => { console.log(props.modelModifiers); // { capitalize: true } }); const emitValue = (e: any) => { let value = e.target.value; if (props.modelModifiers.capitalize) { value = value.charAt(0).toUpperCase() + value.slice(1); } emits("update:modelValue", value); }; </script>
对于又有参数又有修饰符的 v-model 绑定,
生成的 prop 名将是 arg + "Modifiers"
。
父组件
<template> <div> <span>父组件-------myText:{{ myText }}</span> </div> <ChildTpl v-model:title.capitalize="myText" /> </template> <script setup lang="ts"> import { ref } from "vue"; import ChildTpl from "./components/ChildTpl.vue"; const myText = ref("first"); </script> <style scoped></style>
子组件
<template> <div> <input type="text" :value="title" @input="emitValue" /> </div> </template> <script lang="ts" setup> import { onMounted } from "vue"; const emits = defineEmits(["update:title"]); const props = defineProps({ title: { type: String, default: "", }, titleModifiers: { type: Object, default: () => ({}), }, }); onMounted(() => { console.log(props.titleModifiers); // { capitalize: true } }); const emitValue = (e: any) => { let value = e.target.value; value = value.charAt(0).toUpperCase() + value.slice(1); emits("update:title", value); }; </script>
以上是我看了文档后的总结了,如有不意见,欢迎评论指正。
参考网址
https://blog.csdn.net/qq_28378665/article/details/128784126
标签:const,ChildTpl,default,value,vu2,vue3,组件,model From: https://www.cnblogs.com/miangao/p/17189164.html