动态组件
动态组件允许你在运行时根据状态切换渲染不同的组件,而非在编译时固定为某个组件标签。在 Qingkuai 中,只要模板中的组件标签是标识符或成员表达式,且其值会在运行时变化,编译器就会自动将其编译为动态组件——当表达式的值变化时,渲染结果自动切换到最新组件。动态组件可以像普通组件一样接收属性、引用属性和插槽内容。
基本语法
将导入的组件赋值给一个变量,直接在模板中使用该变量作为标签名。当变量的值发生变化时,渲染结果会自动切换到最新组件:
- js
- ts
qk
<lang-js>
import CounterView from "./views/CounterView"
import BadgeView from "./views/BadgeView"
let CurrentView = CounterView
setTimeout(() => {
CurrentView = BadgeView
}, 1000)
</lang-js>
<CurrentView />
qk
<lang-ts>
import CounterView from "./views/CounterView"
import BadgeView from "./views/BadgeView"
let CurrentView: typeof CounterView | typeof BadgeView = CounterView
setTimeout(() => {
CurrentView = BadgeView
}, 1000)
</lang-ts>
<CurrentView />
实例获取
动态组件可以正常接收属性和引用属性。当组件切换时,引用属性绑定的句柄会自动更新为最新组件实例的句柄:
- js
- ts
qk
<lang-js>
import CounterView from "./views/CounterView"
import BadgeView from "./views/BadgeView"
import { nextTick } from "qingkuai"
let CurrentView = CounterView
setTimeout(async () => {
CurrentView = BadgeView
// 等待更新调度完成
await nextTick()
// BadgeView 实例
console.log(handle.value)
}, 1000)
</lang-js>
<CurrentView &handle />
qk
<lang-js>
import CounterView from "./views/CounterView"
import BadgeView from "./views/BadgeView"
import { nextTick } from "qingkuai"
let CurrentView: typeof CounterView | typeof BadgeView = CounterView
setTimeout(async () => {
CurrentView = BadgeView
// 等待更新调度完成
await nextTick()
// BadgeView 实例
console.log(handle.value)
}, 1000)
</lang-js>
<CurrentView &handle />
自动类型推断
配合 TypeScript 时,可以利用 derived 内建方法让编译器自动推断动态组件的联合类型,避免手动声明类型:
qk
<lang-ts>
import CounterView from "./views/CounterView"
import BadgeView from "./views/BadgeView"
let condition = reactive(true)
const CurrentView = derived(() => {
return condition ? CounterView : BadgeView
})
</lang-ts>
<CurrentView />