likes
comments
collection
share

在vue3中更丝滑的去使用tsx

作者站长头像
站长
· 阅读数 3

在vue3中使用更丝滑的去使用tsx

对于喜欢在vue3中使用tsx的小伙伴儿说,去书写属性的类型声明比去写实体的属性更为简单易用,但是在@vitejs/plugin-vue-jsx中,并没有给我们提供这样的使用方式,之前我开发了一个tsx-auto-props插件从一定程度上解决了这个问题。但是这个插件还是没有完全满足我目前的需求,于是我又重新梳理了一下整个的需求,开发了一个新的插件vite-plugin-tsx-resolve-types

这个插件解决了什么问题?

相比tsx-auto-props而言,这个插件不仅仅局限于props的类型声明,并且增加了emits的类型声明的使用方式。所以这次插件可能所能解决的问题并不仅仅局限于tsx-auto-props所能解决的问题。

下面我们通过几个简单的例子来带大家学习一下我们这款插件的用法。

安装

pnpm add -D vite-plugin-tsx-resolve-types

使用

vite.config.ts中配置插件:

import { defineConfig } from 'vite'
import tsxResolveTypes from 'vite-plugin-tsx-resolve-types'
import vueJsx from '@vitejs/plugin-vue-jsx'

export default defineConfig({
    plugins: [
        tsxResolveTypes(),
        vueJsx(),
    ],
})

最基本的用法

你可以抛弃props的属性定义,而直接采用props类型定义的方式来实现属性的声明。

import {defineComponent} from "vue";

interface Props {
    name: string
}

export const Test = defineComponent((props: Props) => {
    return () => (
         <div>{props.name}</div>
    )
})

export const Test1 = defineComponent<Props>((props) => {
    return () => (
        <div>{props.name}</div>
    )
})

export  const Test2 = defineComponent({
    setup(props:Props){
        return ()=>{
             <div>{props.name}</div>
        }
    }
})

export  const Test3 = defineComponent<Props>({
    setup(props){
        return ()=>{
             <div>{props.name}</div>
        }
    }
})



export default defineComponent<Props>((props) => {
    return () => (
        <div>{props.name}</div>
    )
})

默认导出的setup形式

import {defineComponent} from "vue";

interface Props {
    name: string
}
export default defineComponent<Props>({
    setup(props){
        return ()=>{
            return <div>{props.name}</div>
        }
    }
})

复杂类型用法

你可以使用一些比较复杂的类型来定义你的props

interface Props1 {
    foo: string
}

interface Props2 {
    bar: number
}

type Props = Props1 & Props2

export default defineComponent<Props>({
    setup(props){
        return ()=>{
            return <div>{props.foo}{props.bar}</div>
        }
    }
})

interface Props4 extends Props1,Props2{
    baz: boolean
}

export default defineComponent<Props4>({
    setup(props){
        return ()=>{
            return <div>{props.foo}{props.bar}{props.baz}</div>
        }
    }
})

更多复杂用法的例子,大家可以自行探索。

默认值

在之前的tsx-auto-props插件中,我们没有办法给props设置默认值,但是在这个插件中,我们实现了给props类型定义设置默认值的功能。

import { defineComponent } from "vue";
interface Props {
    name: string
    age?: number
}

export default defineComponent<Props>({
    setup(props = {name: 'aibayanyu', age: 18}){
        return ()=>{
            return <div>{props.name}{props.age}</div>
        }
    }
})

const defaults:Props = {
    name: 'aibayanyu',
    age: 18
}

export const Test1 = defineComponent<Props>({
    setup(props = defaults){
        return ()=>{
            return <div>{props.name}{props.age}</div>
        }
    }
})

export const Test2 = defineComponent({
    setup(props:Props = {name: 'aibayanyu', age: 18}){
        return ()=>{
            return <div>{props.name}{props.age}</div>
        }
    }
})

emits类型转换

对于emits的定义,我们也可以使用emits类型定义的方式来实现。

import {defineComponent,SetupContext} from "vue";
interface Emits{
    // 支持类似defineEmits的写法
    click:[Event]
    // 支持函数式的写法
    change:(value:string) => void
}

const Test = defineComponent((props,ctx:SetupContext<Emits>)=>{
    return ()=>{
        return <div onClick={(e)=>ctx.emit('click',e)}>test</div>
    }
})


// 支持行内写法
const Test12 = defineComponent((props,ctx:SetupContext<{click:[string]}>)=>{
    return ()=>{
        return <div onClick={(e)=>ctx.emit('click',e)}>test</div>
    }
})

const Test1 = defineComponent({
    setup(props,ctx:SetupContext<Emits>){
        return ()=>{
            return <div onClick={(e)=>ctx.emit('click',e)}>test</div>
        }
    }
})

const Test2 = defineComponent({
    setup(props,{emit}:SetupContext<Emits>){
        return ()=>{
            return <div onClick={(e)=>emit('click',e)}>test</div>
        }
    }
})

这就是目前我们的插件所提供的能力,如果大家有什么更好的建议,欢迎大家来提交PR/issue,我们一起来完善这个插件。

如果您对我们的项目感兴趣的话,欢迎大家来给我们的项目点个star,您的支持是我们最大的动力。