平缓的、山坡上镶嵌着一块块粉红色的荞麦田,路边铺着碧绿的青稞地,圆木建成的围栏顺着弯弯曲曲的土路,一直通向远方的原始森林,藏式吊脚楼错落有致地分布在路旁,煮奶茶的淡蓝色烟雾中,牛群、羊群时隐时现,整个氛围呈现着一种中世纪乡土意味。
前言
最近自己准备写一个 UI 组件,想对 vue 的 2.x、3.x 可以更深层次的掌握
在架构时,准备全部使用 tsx 书写组件
但遇到了 tsx 中使用 slot 的问题
发现问题
先写了一个基础的 card 组件:
card.tsx:
import Component from 'vue-class-component'
import VanUIComponent from '@packs/common/VanUIComponent'
import { VNode } from 'vue'
import { Prop } from 'vue-property-decorator'
import { CardShadowEnum } from '@packs/config/card'
@Component
export default class Card extends VanUIComponent {
@Prop({
type: String,
default: undefined
}) public headerPadding !: string | undefined
@Prop({
type: String,
default: ''
}) public title !: string
@Prop({
type: String,
default: CardShadowEnum.Hover
}) public shadow !: CardShadowEnum
public static componentName = 'v-card'
public get wrapperClassName(): string {
const list: string[] = ['v-card__wrapper']
list.push(`shadow-${ this.shadow }`)
return list.join(' ')
}
public render(): VNode {
return (
<div class={ this.wrapperClassName }>
<div class="v-card__header" style={ { padding: this.headerPadding } }>
{
this.$slots.title ? <slot name="title" /> : <div>{ this.title }</div>
}
</div>
<div class="v-card__body">
<slot name="default" />
</div>
<div class="v-card__footer"></div>
</div>
)
}
}
在 examples 中使用这个 v-card 的时候:
<template>
<v-card>
<template #title>1111</template>
</v-card>
</template>
<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class Components extends Vue {
}
</script>
<style lang="scss" scoped>
.components__wrapper {
padding: 20px;
}
</style>
我发现渲染后,浏览器不替换 slot 标签:

我在百度、Google寻找了一天也没有解释,在官方文档中仔仔细细阅读后,也没有类似的提示,以及 jsx 编译器的文档中也没有写明,只是声明了如何使用命名 slot。
解决
第二天,我一直在纠结这个,也查了 element-ui 、ant-design-vue 的 UI 组件库中如何书写,也没有找到对应的使用 jsx 使用 slot 的。
不甘放弃的我更换了搜索文字,于是终于找到解决方案,并将代码改为:
...
public render(): VNode {
return (
<div class={ this.wrapperClassName }>
<div class="v-card__header" style={ { padding: this.headerPadding } }>
{
this.$slots.title ?? <div>{ this.title }</div>
}
</div>
<div class="v-card__body">
<slot name="default" />
</div>
<div class="v-card__footer"></div>
</div>
)
}
...
再查看浏览器渲染:

问题解决
后记
在使用 jsx / tsx 时,如果 js 语法本身可以解决的,或本身注册在 this 上的方法,优先使用 js 去做,例如 v-if / v-else 可以使用 双目运算符 替代。实在没有可用的简便方法,再使用 vue 的指令做,例如 v-show 。
到此这篇关于Vue+tsx使用slot没有被替换的问题的文章就介绍到这了,更多相关Vue+tsx slot没有被替换内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!