Vue父子组件通信全面详细介绍

作者:cyg_l02 时间:2024-06-05 09:21:16 

1.Vue父子组件通信方式

父子组件通信方式一般为props和emit组合使用,那么在不同的文件中应该如何使用呢?

|.vue文件和.jsx文件中有什么不同吗?

2.不同文件间的通信方式

1 .父组件vue文件和子组件vue文件

// 父组件App.vue
<HelloWorld :value="count" @update:value="handleAppValue" />
// 子组件HelloWorld.vue
// script
const props = defineProps<{ value: number }>();
const emit = defineEmits<{
 (e: "update:value", value: number): void;
}>();
const handleUpdate = () => {
 emit("update:value", props.value + 1);
};
</script>
<template>
 <div @click="handleUpdate">{{ value }}</div>
</template>

2 .父组件jsx文件和子组件vue文件

// 父组件TsxTest.tsx
// setup内
const handleUpdateValue = (count: number) => {
 value.value = count;
 emit("update:value", value.value);
};
// 注意这里是onUpdate:value
return () => (
 <HelloWorld value={value.value} onUpdate:value={handleUpdateValue} />
);
// 子组件HelloWorld.vue
// script
const props = defineProps<{ value: number }>();
const emit = defineEmits<{
 (e: "update:value", value: number): void;
}>();
const handleUpdate = () => {
 emit("update:value", props.value + 1);
};
</script>
<template>
 <div @click="handleUpdate">{{ value }}</div>
</template>

3 .父组件vue文件和子组件jsx文件

// 父组件App.vue
const count = ref(2);
const handleAppValue = (value: number) => {
 count.value = value;
};
<TsxTest :value="count" @update:value="handleAppValue" />
// 子组件TsxTest.tsx
// script
props: {
 value: {
   type: Number,
   default: 1,
 },
},
emits: ["update:value"],
setup(props, { emit }) {
 const handleUpdateValue = () => {
   emit("update:value", props.value + 1);
 };
 return () => (
   <div onClick={handleUpdateValue}>{props.value}</div>
 );
},

4 .父组件jsx文件和子组件jsx文件

// 父组件TsxParent
const value = ref(1);
const handleUpdateValue = (count: number) => {
 value.value = count;
};
<TsxTest value={value.value} onUpdate:value={handleUpdateValue} />
// 子组件TsxTest.tsx
// script
props: {
 value: {
   type: Number,
   default: 1,
 },
},
emits: ["update:value"],
setup(props, { emit }) {
 const handleUpdateValue = () => {
   emit("update:value", props.value + 1);
 };
 return () => (
   <div onClick={handleUpdateValue}>{props.value}</div>
 );
},

3.如何实现

在componentEmits文件里面可以看到

// componentEmits.ts
// rawArgs就是emit('update:value', count)的count值
let args = rawArgs
const isModelListener = event.startsWith('update:')
//双向绑定的name比如update:value那么就是后面的value值
const modelArg = isModelListener && event.slice(7)
if (modelArg && modelArg in props) {
 const modifiersKey = `${
   modelArg === 'modelValue' ? 'model' : modelArg
 }Modifiers`
 // 是否有modifiersKey比如trim/number
 const { number, trim } = props[modifiersKey] || EMPTY_OBJ
 if (trim) {
   args = rawArgs.map(a => a.trim())
 }
 if (number) {
   args = rawArgs.map(toNumber)
 }
}

为啥modifiersKey会拼接Modifiers字符串呢?

因为在vModel处理时会获取父组件传过来的modifiers并进行处理拼接

// vModel.ts
// 对eventName进行处理,arg不存在则认为是onUpdate:modelValue
const eventName = arg
 ? isStaticExp(arg)
   ? `onUpdate:${arg.content}`
   : createCompoundExpression(['"onUpdate:" + ', arg])
 : `onUpdate:modelValue`
const modifiersKey = arg
 ? isStaticExp(arg)
   ? `${arg.content}Modifiers`
   : createCompoundExpression([arg, ' + "Modifiers"'])
 : `modelModifiers`

然后在进行handler处理

// componentEmits.ts 接上
let handlerName
let handler =
 // toHandlerKey就行处理evnet变成on${capitalize(str)}
 props[(handlerName = toHandlerKey(event))] ||
 // also try camelCase event handler (#2249)
 props[(handlerName = toHandlerKey(camelize(event)))]
// for v-model update:xxx events, also trigger kebab-case equivalent
// for props passed via kebab-case
if (!handler && isModelListener) {
 handler = props[(handlerName = toHandlerKey(hyphenate(event)))]
}
if (handler) {
 // callWithAsyncErrorHandling就是函数执行,然后进行了错误处理
 callWithAsyncErrorHandling(
   handler,
   instance,
   ErrorCodes.COMPONENT_EVENT_HANDLER,
   args
 )
}

简单来说emit函数就是语法糖

<TsxTest value={value.value} onUpdate:value={handleUpdateValue} />
<TsxTest :value="count" @update:value="handleAppValue" />

上面两种方式的处理函数[onUpdate:value/@update:value]都会在emit里面变成这样

emit('update:value', count)
// 执行emit其实就行下面的执行
props.['onUpdate:value'](count)

来源:https://blog.csdn.net/cyg_l02/article/details/127411872

标签:vue,父子组件通信
0
投稿

猜你喜欢

  • python的Template使用指南

    2023-10-14 01:30:58
  • python实现selenium截图的两种方法

    2023-08-16 06:26:57
  • Python编写通讯录通过数据库存储实现模糊查询功能

    2024-01-16 06:39:55
  • Django REST framework 视图和路由详解

    2022-10-16 00:29:32
  • mysql常用函数汇总(分享)

    2024-01-29 03:30:56
  • 支付宝小程序向用户发红包的实现方法

    2022-12-19 22:58:58
  • C#数据导入/导出Excel文件及winForm导出Execl总结

    2023-07-18 04:04:43
  • Python实现读取文件夹按数字排序功能

    2023-08-24 02:12:45
  • flask-restful使用总结

    2023-02-10 13:24:21
  • element-ui表格数据转换的示例代码

    2023-07-02 17:00:23
  • python 实现有道翻译功能

    2022-03-25 17:30:55
  • 很全面的Mysql数据库、数据库表、数据基础操作笔记(含代码)

    2024-01-15 11:19:42
  • python利用正则表达式提取字符串

    2021-12-08 15:13:29
  • asp源码实现Access数据库的建立或压缩

    2007-08-06 16:54:00
  • pytorch Dropout过拟合的操作

    2023-11-26 16:12:18
  • 一个简单的ASP计数器代码

    2010-04-24 15:49:00
  • 如何爬取通过ajax加载数据的网站

    2022-05-03 15:06:01
  • python列表的逆序遍历实现

    2021-08-02 02:01:28
  • Python openpyxl读取单元格字体颜色过程解析

    2023-02-09 06:57:02
  • 一文掌握go的sync.RWMutex锁

    2024-04-26 17:28:30
  • asp之家 网络编程 m.aspxhome.com