vue父子组件之间的通信(Vue父子组件通信全面详细介绍)
导读:1.Vue父子组件通信方式 父子组件通信方式一般为props和emit组合使用,那么在不同的文件中应该如何使用呢?...
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父子组件通信内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
声明:本站所有文章,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织 ,在未征得本站同意时 ,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!