一年又要到年底了,vue3.0都已经出来了,我们也不能一直还停留在过去的js中,是时候学习并且在项目中使用一下Ts了。

  如果说jsx是基于js的话,那么tsx就是基于typescript的

  废话也不多说,让我们开始写一个Tsx形式的button组件,

  ts真的不仅仅只有我们常常熟知的数据类型,还包括接口,类,枚举,泛型,等等等,这些都是特别重要的

  项目是基于vue-cli 3.0 下开发的,可以自己配置Ts,不会的话那你真的太难了

  

 

     我们再compenonts中新建一个button文件夹,再建一个unit文件夹,button放button组件的代码,unit,放一些公共使用模块

  我们再button文件夹下创建 ,index .tsx放的button源码,index.less放的是样式,css也是不可缺少的

       

 

   分析一下button需要的一些东西

  第一个当然是props,还有一个是点击事件,所以我们第一步就定义一下这两个类型

复制代码
type ButtonProps = {   tag: string,   size: ButtonSize,   type: ButtonType,   text: String }  type ButtonEvents = {   onClick?(event: Event) :void } type ButtonSize = 'large' | 'normal' | 'small' | 'mini' type ButtonType = 'default' | 'primary' | 'info' | 'warning' | 'danger'
复制代码

  因为button是很简单的组件,内部也没有一些特别的状态需要改变,所以我们用函数式组件的方式去写(之后的render会用到这个方法)

复制代码
function Button (h: CreateElement, props: ButtonProps, slots: DefaultSlots, ctx: RenderContext<ButtonProps>) {   const { tag, size, type } = props   let text   console.log(slots)   text = slots.default ? slots.default() : props.text   function onClick (event: Event) {     emit(ctx, 'click', event)   }   let classes = [size,type]   return (     <tag       onClick = {onClick}       class = {classes}     >       {text}     </tag>  ) }
复制代码

  h 是一个预留参数,这里并没有用到 ,CreateElement  这个是vue从2.5之后提供的一个类型,也是为了方便在vue项目上使用ts

  props 就是button组件的传入的属性,slots插槽,ctx,代表的是当前的组件,可以理解为当前rendercontext执行环境this

  DefaultSlots是我们自定义的一个插槽类型

复制代码
export type ScopedSlot<Props = any> = (props?: Props) => VNode[] | VNode | undefined;  export type ScopedSlots = {   [key: string]: ScopedSlot | undefined; }
复制代码

  插槽的内容我们都是需要从ctx中读取的,默认插槽的key就是defalut,具名插槽就是具体的name

  button放发内部还有一个具体的点击事件,还有一个emit方法,从名字我们也可以看的出,他是粗发自定义事件的,我们这里当然不能使用this.emit去促发,

  所以我们需要单独这个emit方法,我们知道组件内所以的自定义事件都是保存在listeners里的,我们从ctx中拿取到所以的listeners

复制代码
 
 
  import { RenderContext, VNodeData } from 'vue' // 从vue中引入一些类型

function
emit (context: RenderContext, eventName: string, ...args: any[]) { const listeners = context.listeners[eventName] if (listeners) { if (Array.isArray(listeners)) { listeners.forEach(listener => { listener(...args) }) } else { listeners(...args) } }
<