vue2结合vue-property-decorator中tsx相关写法

基础写法

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
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值