以element-plus dialog对话框为例
// 子组件
import { defineComponent } from 'vue'
export default defineComponent({
props: {
modelValue: {
type: Boolean,
required: false
}
},
emits: ['update:modelValue'],
setup(props, { emit, slots }) {
const handleClose = () => {
emit('update:modelValue', false)
}
return () => (
<>
<el-button
type="primary"
onClick={() => {
emit('update:modelValue', true)
}}
>
内部打开
</el-button>
<el-dialog
// 手动更新值,不使用v-model,会使值只读。解决:使用自身value
modelValue={props.modelValue}
// 关闭
onClose={handleClose}
// 更新
onUpdate:modelValue={newValue =>
emit('update:modelValue', newValue)
}
title="Dialog Title"
v-slots={{
// 组件内部插槽
footer: () => <span>2222222222</span>
}}
>
<span>This is a dialog content.</span>
{/* 组件抛出插槽 */}
{slots.content?.()}
</el-dialog>
</>
)
}
})
父组件
<el-button @click="open = true">打开弹窗</el-button>
<test v-model="open">
<template #content>11111</template>
</test>
传递 Props
// ChildComponent.tsx
import { defineComponent } from 'vue';
export default defineComponent({
props: {
title: {
type: String,
required: true,
},
},
setup(props) {
return () => (
<div>
<h1>{props.title}</h1>
</div>
);
},
});
// ParentComponent.tsx
import { defineComponent } from 'vue';
import ChildComponent from './ChildComponent';
export default defineComponent({
setup() {
return () => (
<div>
<ChildComponent title="Hello, World!" />
</div>
);
},
});
使用 Emit
// ChildComponent.tsx
import { defineComponent } from 'vue';
export default defineComponent({
emits: ['customEvent'],
setup(_, { emit }) {
const handleClick = () => {
emit('customEvent', 'This is a message from the child component');
};
return () => (
<button onClick={handleClick}>Click me</button>
);
},
});
// ParentComponent.tsx
import { defineComponent } from 'vue';
import ChildComponent from './ChildComponent';
export default defineComponent({
setup() {
const handleCustomEvent = (message: string) => {
console.log(message);
};
return () => (
<div>
<ChildComponent onCustomEvent={handleCustomEvent} />
</div>
);
},
});
使用 Slots
// ChildComponent.tsx
import { defineComponent } from 'vue';
export default defineComponent({
setup(_, { slots }) {
return () => (
<div>
<h1>{slots.header?.()}</h1>
<div>{slots.default?.()}</div>
<footer>{slots.footer?.()}</footer>
</div>
);
},
});
// ParentComponent.tsx
import { defineComponent } from 'vue';
import ChildComponent from './ChildComponent';
export default defineComponent({
setup() {
return () => (
<ChildComponent>
{{
header: () => <span>Header Content</span>,
default: () => <p>Main Content</p>,
footer: () => <span>Footer Content</span>,
}}
</ChildComponent>
);
},
});