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

 更新时间:2022年10月25日 08:38:54   作者:cyg_l02  
这篇文章主要介绍了React中父子组件通信详解,在父组件中,为子组件添加属性数据,即可实现父组件向子组件通信,文章通过围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

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)

到此这篇关于Vue父子组件通信全面详细介绍的文章就介绍到这了,更多相关Vue父子组件通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue 悬浮窗且带自动吸附功能实现demo

    vue 悬浮窗且带自动吸附功能实现demo

    这篇文章主要为大家介绍了vue 悬浮窗且带自动吸附功能实现demo,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • vue2老项目中node-sass更换dart-sass的操作方法

    vue2老项目中node-sass更换dart-sass的操作方法

    这篇文章主要介绍了vue2老项目中node-sass更换dart-sass的操作方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-07-07
  • Vue.js 使用AntV X6的示例步骤

    Vue.js 使用AntV X6的示例步骤

    X6 是 AntV 旗下的图编辑引擎,提供了一系列开箱即用的交互组件和简单易用的节点定制能力,方便我们快速搭建流程图、DAG 图、ER 图等图应用。接下来就看看vue如何使用它
    2021-05-05
  • 原生JS Intersection Observer API实现懒加载

    原生JS Intersection Observer API实现懒加载

    这篇文章主要为大家介绍了原生JS Intersection Observer API实现懒加载示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • uniapp和vue的区别详解

    uniapp和vue的区别详解

    这篇文章主要介绍了uniapp和vue的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-10-10
  • vue el-table实现动态添加行和列具体代码

    vue el-table实现动态添加行和列具体代码

    最近遇到一个动态增加行和列的需求,所以这里给大家总结下,这篇文章主要给大家介绍了关于vue el-table实现动态添加行和列的相关资料,需要的朋友可以参考下
    2023-09-09
  • vue+el-element中根据文件名动态创建dialog的方法实践

    vue+el-element中根据文件名动态创建dialog的方法实践

    本文主要介绍了vue+el-element中根据文件名动态创建dialog的方法实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Vue中前后端使用WebSocket详细代码实例

    Vue中前后端使用WebSocket详细代码实例

    websocket通信是很好玩的,也很有用的的通信方式,下面这篇文章主要给大家介绍了关于Vue中前后端使用WebSocket的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • vue3项目目录结构示例详解

    vue3项目目录结构示例详解

    更好的了解项目的目录结构,能更好的去开发项目,下面这篇文章主要给大家介绍了关于vue3项目目录结构的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • vue-router路由跳转问题 replace

    vue-router路由跳转问题 replace

    这篇文章主要介绍了vue-router路由跳转问题 replace,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09

最新评论