基础写法
import { Component, Prop, Vue } from 'vue-property-decorator'
@Component
export default class TsxVue extends Vue {
render(h, hack) {
return <div>测试tsx</div>
}
}
Prop写法
import { Component, Prop, Vue } from 'vue-property-decorator'
@Component
export default class TsxVue extends Vue {
@Prop() text!: string
@Prop({ default: true }) disabled!: boolean
render(h:CreateElement) {
return <el-button type="primary" disabled={this.disabled}></el-button>
}
}
slot插槽写法
默认插槽
不带参数的写法
组件template
模板写法
<el-button :disabled="disabled">
<slot></slot>
</el-button>
组件使用
<tsx-vue>测试一下</tsx-vue>
组件tsx写法
import { Component, Prop, Vue } from 'vue-property-decorator'
@Component
export default class TsxVue extends Vue {
@Prop() text!: string
@Prop({ default: true }) disabled!: boolean
render(h) {
return (
<el-button type="primary" disabled={this.disabled}>
{this.$scopedSlots.default && this.$scopedSlots.default(null)}
</el-button>
)
}
}
带参数的slot写法
组件模板定义
<el-button>
<slot :info="info"></slot>
</el-button>
组件调用
<tsx-vue text="测试一下">
<template #default="{ info }">{{ info }}</template>
</tsx-vue>
组件tsx定义
import { Component, Prop, Vue } from 'vue-property-decorator'
@Component({
render(h, hack) {
const proxy: TsxVue = (this as any)._renderProxy
return (
<el-button type="primary" disabled={proxy.disabled}>
{proxy.$scopedSlots.default && proxy.$scopedSlots.default({info: this.info})}
</el-button>
)
}
})
export default class TsxVue extends Vue {
@Prop() text!: string
@Prop({ default: true }) disabled!: boolean
info = 'info'
}
命名插槽
组件模板写法
<div>
<el-button>
<slot :info="{info}"></slot>
</el-button>
<span>
<slot name="other" :info="{info}"></slot>
</span>
</div>
组件调用
<tsx-vue text="测试一下">
<template #default="{ info }">{{ info }}</template>
<template #other="{ info }">{{ info }}</template>
</tsx-vue>
在写插槽调用时,一定要先判断该插槽是否存在,因为用户可以添加插槽也可以不添加。
import { Component, Prop, Vue } from 'vue-property-decorator'
@Component({
render(h, hack) {
const proxy: TsxVue = (this as any)._renderProxy
return (
<div>
<el-button type="primary" disabled={proxy.disabled}>
{proxy.$scopedSlots.default({ info: proxy.info })}
</el-button>
<span>{proxy.$scopedSlots.other && proxy.$scopedSlots.other({ info: proxy.info2 })}</span>
</div>
)
}
})
export default class TsxVue extends Vue {
@Prop() text!: string
@Prop({ default: true }) disabled!: boolean
info = 'info'
info2 = 'info2'
}
父组件调用子组件
模板写法
<template>
<child-com>
<template #default="{info}">
<div>{{info}}</div>
</template>
<template #other="{info}">{{info}}</template>
</child-com>
</template>
在父组件中调用子组件并自定义slot的tsx写法:
import { Component, Prop, Vue } from 'vue-property-decorator'
import ChildCom from './test'
import './parent.scss'
@Component({
components: { ChildCom },
render(h, hack) {
const proxy: ParentCom = (this as any)._renderProxy
return (
<div class="container">
<span>{proxy.parantData}</span>
<child-com
scopedSlots={{
default: (scope: any) => {
return <div>{scope.info}</div>
},
other: (scope: any) => {
return scope.info
}
}}></child-com>
</div>
)
}
})
export default class ParentCom extends Vue {
@Prop() test!: string
parantData = 'I am Parent'
}
自定义指定的写法
例如element中的v-loading
;
<div v-loading="showLoading"></div>
以上写法在tsx中可按如下写法:
render(h) {
const directives = [{ name: 'loading', value: this.showLoading }]
return <div {...{ directives }}/>
}
v-bind="$attrs"
的写法
render(h) {
return <div {...{attrs: this.$attrs}}/>
}
指令修饰符的写法
例如<div v-loading.fullscreen.lock="showLoading"></div>
可以写作
render(h) {
const directives = [{ name: 'loading', value: this.showLoading,modifiers: { fullscrenn: true, lock: false } }]
return <div {...{ directives }}/>
}
注意事项
注意render的第一个参数必须写h
,不能命名为其他的,否则无法正确渲染
例如:
import { Component, Prop, Vue } from 'vue-property-decorator'
@Component({
render(createElement, hack) {
const proxy = this._renderProxy
return <div><span>{proxy.parentData}</span></div>
}
})
export default class TsxVue extends Vue {
parentData = 'test data'
}
实际生成的render函数大致是以下这种形式
render(createElement, hack) {
return h('div',{},[
h('span', {}, this.parentData)
])
}
此时内部的h没有正确的转为传入的createElement
,导致页面组件渲染空白。为了应对这一问题,render函数默认传入h,不要重命名
@Provide 的写法传递组件实例
如何通过provide向子组件传递整个父组件的实例?
通常js中的写法如下:
//父组件provide
export default {
provide() {
return {
parent: this
}
}
}
//子组件inject
export default {
inject: {
parent: {default: null}
}
}
在ts中,以上方法依旧可用
import { Component,Vue } from 'vue-property-decorator'
@Component({
provide() {
return {
parent: this
}
}
})
export default class TsxVue extends Vue {}
如果想利用注释@Provide
的写法,可以像以下这种形式
父组件
import { Component, Provide } from 'vue-property-decorator'
@Component
export default class TsxVue extends Vue {
@Provide() parent!:TsxVue = this
}
子组件
import { Component, Inject } from 'vue-property-decorator'
@Component
export default class extends Vue {
@Inject({default:null}) parent!:TsxVue
}