在Vue 3中,有多种方法来声明、创建和渲染组件。以下是全面的总结:
- 组件声明方法:
typescript
// 选项式API
export default defineComponent({
props: {},
setup() {}
})
// 组合式API
export default {
setup() {}
}
// <script setup>语法糖
<script setup>
// 直接编写逻辑
</script>
// 传统的类组件
export default class MyComponent extends Vue {}
- 组件创建方法:
typescript
// 普通组件
const MyComponent = defineComponent({})
// 函数式组件
const FunctionalComponent: FunctionalComponent = (props, ctx) => {
return h('div', props.text)
}
// 动态组件
const componentsMap = {
ComponentA,
ComponentB
}
- 组件渲染方式:
vue
<!-- 模板渲染 -->
<template>
<MyComponent />
<component :is="dynamicComponent" />
</template>
<!-- 动态渲染 -->
<script setup>
import { h, resolveComponent } from 'vue'
// 渲染方式1:h()函数
const VNode = h(MyComponent, { props })
// 渲染方式2:渲染函数
render() {
return h('div', [
h(MyComponent),
h(resolveComponent('el-button'))
])
}
// 渲染方式3:动态组件
const currentComponent = shallowRef(ComponentA)
</script>
<!-- 异步组件 -->
<script setup>
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() =>
import('./components/MyComponent.vue')
)
</script>
<!-- 内置组件渲染 -->
<component :is="tabs[currentTab]" />
- 高级组件创建:
typescript
// 高阶组件
function withLoading(Component) {
return {
setup() {
const loading = ref(true)
return () => h(Component, { loading })
}
}
}
// 泛型组件
interface Props<T> {
data: T[]
}
function GenericComponent<T>(props: Props<T>) {
return h('div', props.data)
}
- 渲染控制:
vue
<!-- 条件渲染 -->
<template>
<MyComponent v-if="condition" />
<MyComponent v-else />
<!-- 列表渲染 -->
<MyComponent
v-for="item in list"
:key="item.id"
:data="item"
/>
</template>
- 插槽渲染:
vue
<!-- 默认插槽 -->
<MyComponent v-slot="{ data }">
{{ data }}
</MyComponent>
<!-- 具名插槽 -->
<MyComponent>
<template #header>Header</template>
<template #default>Content</template>
</MyComponent>
- 动态组件技巧:
vue
<script setup>
import { ref, shallowRef } from 'vue'
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
// 动态切换组件
const current = shallowRef(ComponentA)
</script>
<template>
<component :is="current" />
<button @click="current = ComponentB">切换</button>
</template>
- 异步组件:
typescript
// 基本异步
const AsyncComponent = defineAsyncComponent(() =>
import('./MyComponent.vue')
)
// 带加载和错误状态
const AsyncComponent = defineAsyncComponent({
loader: () => import('./MyComponent.vue'),
loadingComponent: LoadingComponent,
errorComponent: ErrorComponent,
delay: 200,
timeout: 3000
})
这些方法涵盖了Vue 3中组件声明、创建和渲染的主要技术和模式。根据具体场景选择最适合的方式。
关键建议:
- 推荐使用
<script setup>
语法 - 优先使用组合式API
- 根据实际需求选择合适的组件创建方式
- 注意性能和代码可读性