v-model

首先vue的单项数据流特性导致子组件只能接收父组件传递的数据,也就是只能读不能改,所以若要修改父组件的数据便只能由父组件自己去改。

根据这个特性我们实现父子传值的思路就是:父组件向子组件传递一个值,然后子组件修改后,告诉父组件我把值改了。

具体的实现步骤就是:(1)先通过自定义属性进行父传子;(2)再通过emit进行子传父;(3)然后在父组件中通过自定义事件去接收,然后修改。

通过v-model 传值,可以省略第三步,也就是不用父组件写修改方法,只需要在子组件中使用 emit 即可,由 v-model 实现修改操作。这里的 emit 的写法有不同,具体写法参考下面的示例代码。

TIP

父组件:子组件标签自定义属性绑定 v-model:自定义属性 = "值"

子组件emit("update:自定义属性",修改的值)

v-model既能父传子,又能子传父

v-model本质

1<!-- 使用v-model指令 -->
2<input type="text" v-model="val" />
3
4<!-- v-model的本质是下面这行代码 -->
5<input
6 type="text"
7 :value="val"
8 @input="val = $event.target.value"
9/>

v-model用在组件标签上

1<template>
2  <h2>父组件</h2>
3  <child-comp v-model="data"/> 
4  <!-- v-model的本质是下面这行代码 -->
5  <child-comp 
6	:modelValue="data" 
7	@update:modelValue="data = $event" 
8  /> 
9
10  <!-- modelValue的名也是可以更换,例如改成abc --> // [!code warning]
11  <child-comp v-model:abc="data"/> // [!code warning]
12  <child-comp // [!code warning]
13	:abc="data" // [!code warning]
14	@update:abc="data = $event" // [!code warning]
15  /> // [!code warning]
16</template>
17
18<script lang="ts" name="ParentComp" setup>
19import ChildComp from "@/components/ChildComp.vue";
20import {ref} from "vue";
21let data = ref('123')
22</script>
1<template>
2  <h2>子组件</h2>
3  <!--
4    1.将接收的value值赋给input元素的value属性,目的是:为了呈现数据
5    2.给input元素绑定原生input事件,触发input事件时,进而触发update:model-value事件
6  -->
7  <input 
8	type="text" 
9	:value="modelValue" 
10	@input="emit('update:model-value', $event.target.value)" 
11  /> 
12
13  <input // [!code warning]
14	type="text" // [!code warning]
15	:value="abc" // [!code warning]
16	@input="emit('update:abc', $event.target.value)" // [!code warning]
17  /> // [!code warning]
18</template>
19
20<script lang="ts" name="ChildComp" setup>
21defineProps(['modelValue']) 
22const emit = defineEmits(['update:model-value']) 
23
24defineProps(['abc']) // [!code warning]
25const emit = defineEmits(['update:abc']) // [!code warning]
26</script>

:::

$event 到底是啥?啥时候能 .target

对于原生事件,$event 就是事件对象,能 .target

对于自定义事件,$event 就是触发事件时所传递的数据,不能 .target