关于vue3的v_model双向绑定:
v3.4之前使用 defineProps
v3.4之后使用 defineModel
文档:https://vuejs.org/guide/components/v-model.html
主要用法如下:
1>常规的单属性双向绑定
ex:
定义子组件Child.vue:
<script setup lang="ts">
const title = defineModel({
default: "我是title的默认值",// 设置v-moddel的默认值
// required: true, // 设置为必传属性,当在父组件使用的时候
});
const change = () => {
title.value = "我是title的新值"; //这里改变 v-model 的值,会在下面同步修改
}
</script>
<template>
<Button @click="change">修改...</Button>
<div>parent bound v-model is: {{ title }}</div>
</template>
2>通过父子组件使用
ex:
定义父组件Parent.vue:
<script setup lang="ts">
const count = ref("haha");
const say = () => {
count.value = "world";
};
</script>
<template>
<Button @click="say">添加</Button>
<input type="text" :value="count">// 同时,v-model的值会在这里展示,如果 子组件 触发了 change 事件,那么 父组件的count值也会改变
<Child v-model="count"></Child> // 这里通过count给v-model传值,当count 没有值 比如 onst count = ref(); 的时候 ,会使用 子组件定义的 default 值
</template>
3>可以在通过 defineModel 定义 v-model 的时候,限定 v-model的类型,如下:
const title = defineModel<boolean>(); // 指定为 bool 型
4>可以通过给 v-model 绑定参数,可以实现为 v-model 定义名称,在一个组件下有多个 v-model 属性的时候,必须要这么做, 单个的时候直接 defineModel()就可以了,可能是因为默认名称只能有一个吧
ex:
常规使用:
子组件:
<script setup>
const firstName = defineModel('haha')
const lastName = defineModel('hehe')
</script>
<template>
<input type="text" v-model="firstName" />
<input type="text" v-model="lastName" />
</template>
父组件:
<script setup>
import { ref } from 'vue'
import UserName from './UserName.vue'
const first = ref('John')
const last = ref('Doe')
</script>
<template>
<h1>{{ first }} {{ last }}</h1>
<UserName
v-model:haha="first"
v-model:hehe="last"
/>
</template>
添加额外属性使用:
子组件:
<script setup>
const firstName = defineModel('haha')
const lastName = defineModel('hehe', {
default: "这个是默认值",
//required: true
})
const change = () => {
lastName.value = "做个修改"
}
</script>
<template>
<input type="text" v-model="firstName" />
<input type="text" v-model="lastName" />
<button @click="change">修改一下</button>
</template>
父亲组件:
<script setup>
import { ref } from 'vue'
import UserName from './UserName.vue'
const first = ref('John')
const last = ref('Doe')
</script>
<template>
<h1>{{ first }} {{ last }}</h1>
<UserName
v-model:haha="first"
/>
</template>
5>可以为 v-model 定义修改器(modifiers),一个v-model 属性上只能定义一个修改器,定义多个不生效
ex:
父组件:
<script setup>
import { ref } from 'vue'
import MyComponent from './MyComponent.vue'
const myText = ref('')
</script>
<template>
This input capitalizes everything you enter:
<p>{{ myText }}</p>
<MyComponent v-model.firtToUpper="myText" />
</template>
子组件:
<script setup>
import { computed } from 'vue'
const [title, modifiers] = defineModel({
set(value) {
if (modifiers.firtToUpper) {
return value.charAt(0).toUpperCase() + value.slice(1)
}
return value
}
})
const change = () => {
title.value = "change the value"
}
</script>
<template>
<button @click="change">修改</button>
<input type="text" v-model="title" />
</template>
我发现 modifiers 参数是可以自定义的,可以定义为其它的,比如我这里改为 dodo:
<script setup>
import { computed } from 'vue'
const [title, dodo] = defineModel({
set(value) {
if (dodo.firtToUpper) {
return value.charAt(0).toUpperCase() + value.slice(1)
}
return value
}
})
const change = () => {
title.value = "change the value"
}
</script>
<template>
<button @click="change">修改</button>
<input type="text" v-model="title" />
</template>
6> 将修改器使用到多个 v-model 属性,下面这个是官网的例子,我认为没什么用,只是做了 console 打印,我以为可以像上面一样,对数据处理,需要自己尝试
ex:
子组件:
<UserName
v-model:haha.capitalize="first"
v-model:hehe.uppercase="last"
/>
父组件:
<script setup>
const [firstName, firstNameModifiers] = defineModel('haha')
const [lastName, lastNameModifiers] = defineModel('hehe')
console.log(firstNameModifiers) // { capitalize: true }
console.log(lastNameModifiers) // { uppercase: true}
</script>
