Vue3 中V-model的学习 尚硅谷

文章详细解释了Vue3中v-model的工作原理,如何在父组件和子组件之间实现数据的双向绑定。v-model会将父组件的数据转换为modelValue传递给子组件,子组件通过defineProps接收,并通过defineEmits定义触发的自定义事件来更新父组件的数据。此外,文章还展示了如何处理多个v-model绑定到同一子组件的情况,以及如何通过自定义事件进行通信。
摘要由CSDN通过智能技术生成

代码源自尚硅谷最新课程

本人对Vue3的了解尚浅,很多知识停留在Vue2中,所以对Vue3中的V-model,很不了解

如有问题欢迎指正

首先的问题是,在Vue3中v-model 会自动将父组件的数据作为props传递给子组件props.

而子组件也可以通过definePropos接受数据就像一下代码中

 <Child v-model="money"></Child> 对子组件Child 传递名为money的数据

let props = defineProps(["modelValue"]); 而子组件可以通过 defineProps接受数据

但是我在这里产生了一个疑问,为什么在父组件内v-model命名是money 但是接受名却是modelValue???? 

带着疑问我询问了chagpt

给出的答案如下

这是因为 v-model 在子组件上会自动将父组件的数据 model 转换为 modelValue prop 传递给子组件。也就是说,当你在父组件中使用 v-model 绑定子组件时,例如:

html
<Child v-model="money" />

v-model 会将 money 数据作为名为 modelValue 的 prop 传给 Child 组件。所以在子组件中,我们需要使用 modelValue 作为 props 选项的键来接收这个 prop:

js
let props = defineProps(["modelValue"]);  

而不管父组件绑定时的数据 model 是什么名称,v-model 都会自动将其转换为 modelValue 传递给子组件。这么做的目的是让子组件可以和任何使用 v-model 绑定它的父组件通信,而不依赖具体的数据 model 是什么名称。如果 v-model 不做这个转换,那子组件就需要知道所有可能使用它的父组件的数据模型的名称,这显然是不现实的。所以,v-model 做了这一转换,让子组件只需要关心 modelValue 这个 prop,并通过它和任何父组件实现双向绑定通信。这里可能会产生一些疑问:如果多个父组件同时使用 v-model 绑定同一个子组件,那数据会有冲突吗?答案是不会的,因为 v-model 在每个父组件内部都创建单独的 prop 和事件:

这下我总算是明白了这个问题/

然后我又遇到了移一处不能理解的地方,就是v-model能绑定自定义事件还是啥????

  <Child1 v-model:pageNo="pageNo" v-model:pageSize="pageSize"></Child1>

后面我才知道

这段是通过v-mode传递给子组件pageNo和pageSize,再通过子组件内的

let $emit = defineEmits(["update:pageNo", "update:pageSize"]);

来监听,并更新父组件数据

然后通过

    <button @click="$emit('update:pageSize', pageSize + 4)">

  <button @click="handler">pageNo{{ pageNo }}</button>

const handler = () => {

  $emit("update:pageNo", props.pageNo + 3);

};

来触发事件

总结(狗头 不是自己写的:P):

1. v-model 可以在父子组件间创建双向绑定。父组件使用 v-model 绑定子组件时,Vue 会自动创建名为 modelValue 的 prop 传递给子组件,并监听子组件触发的 update:modelValue 事件更新父组件的数据。子组件需要定义接收 modelValue 的 props,并触发 update:modelValue 事件更新 prop。

2. defineProps 用于定义子组件接收的 props,defineEmits 定义子组件可以触发的事件。这有助于声明组件的 API,方便其他开发者理解。

3. 带有 update: 前缀的事件用于更新 prop。子组件触发 update:propName 事件,父组件就会更新传入的 propName prop。这是 Vue 组件实现双向绑定的一种设计模式。

4. 子组件不应该直接操作传入的 prop。更好的方式是:在子组件内部用 ref 或 reactive 管理数据,触发自定义事件时传入内部数据的最新值,父组件监听事件并更新 prop 同步最新值。这可以让子组件内部维护其状态与逻辑,父组件只负责同步。这符合组件的封装思想,可以构建出更加独立可靠的组件。

5. 自定义事件是子组件暴露给外部的一种通信方式。通过 emit 触发自定义事件,外部监听事件做出响应。这使得子组件具有了主动通知外部的能力。自定义事件应在 defineEmits 中定义,以声明组件 API 并获得在开发环境的警告功能。

这是父组件的源码

<template>
  <div>
    <h1>v-model:钱数{{ money }}{{pageNo}}{{pageSize}}</h1>
    <input type="text" v-model="info" />
    <hr />
    <!-- props:父亲给儿子数据 -->
    <!-- <Child :modelValue="money" @update:modelValue="handler"></Child> -->
    <!-- 
       v-model组件身上使用
       第一:相当有给子组件传递props[modelValue] = 10000
       第二:相当于给子组件绑定自定义事件update:modelValue
     -->
    <Child v-model="money"></Child>
    <hr />
    <Child1 v-model:pageNo="pageNo" v-model:pageSize="pageSize"></Child1>
  </div>
</template>

<script setup lang="ts">
//v-model指令:收集表单数据,数据双向绑定
//v-model也可以实现组件之间的通信,实现父子组件数据同步的业务
//父亲给子组件数据 props
//子组件给父组件数据 自定义事件
//引入子组件
import Child from "./Child.vue";
import Child1 from "./Child1.vue";
import { ref } from "vue";
let info = ref("");
//父组件的数据钱数
let money = ref(10000);
//自定义事件的回调
const handler = (num) => {
  //将来接受子组件传递过来的数据
  money.value = num;
};

//父亲的数据
let pageNo = ref(1);
let pageSize = ref(3);
</script>

接下来分别是子组件的源码

<template>
  <div class="child">
    <h3>钱数:{{ modelValue }}</h3>
    <button @click="handler">父子组件数据同步</button>
  </div>
</template>

<script setup lang="ts">
//接受props
let props = defineProps(["modelValue"]);
let $emit = defineEmits(['update:modelValue']);
//子组件内部按钮的点击回调
const handler = ()=>{
   //触发自定义事件
   $emit('update:modelValue',props.modelValue+1000);
}
</script>

<template>
  <div class="child2">
    <h1>同时绑定多个v-model</h1>
    <button @click="handler">pageNo{{ pageNo }}</button>
    <button @click="$emit('update:pageSize', pageSize + 4)">
      pageSize{{ pageSize }}
    </button>
  </div>
</template>

<script setup lang="ts">
let props = defineProps(["pageNo", "pageSize"]);
let $emit = defineEmits(["update:pageNo", "update:pageSize"]);
//第一个按钮的事件回调
const handler = () => {
  $emit("update:pageNo", props.pageNo + 3);
};
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值