Vue3中TSX的使用方式

第一步:安装插件

npm install @vitejs/plugin-vue-jsx -D

第二步: 在vite.config.ts中进行引入插件和注册插件

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx' // 引入插件

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    vueJsx(), // 注册插件
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

第三步:使用方法

写一个.tsx文件,像组件一样引入页面和使用

如:xue.tsx

在页面引用 import xue from './components/xue.tsx'

在页面使用 <xue></xue>

方法一:导出渲染函数 在里面直接return标签代码

export default function () {
    return (<div>东北下雪了</div>)
}

方法二: 用render渲染函数返回标签

// 在组件中引入
import {defineComponent} from 'vue';
// 它其实是一个函数,他里面可以放一个对象, 有点类似vue2的写法

// 下面定一个render渲染函数,里面返回标签,
// 注意tsx里面使用变量使用的是单花括号
import {defineComponent} from 'vue';
export default defineComponent({
  data() {
      return {
        name: '张三'
      }
  },
  render () {
    return (<div>{this.name}</div>)
  }
})

方法三:使用setup函数,然后返回一个渲染函数

import {defineComponent} from 'vue';
export default defineComponent({
  setup() {
    return () => (<div>广东没下雪</div>)
  }
})

语法支持方面

1.v-show 支持 <div v-show={true}></div>

如果使用vue3的ref定义变量,不会自动解包,要手动解包 .value

import {defineComponent, ref} from 'vue';
export default defineComponent({
  setup() {
    const flag = ref(false);
    return () => (<div v-show={flag.value}>广东没下雪</div>)
  }
})

2.v-if 不支持,需求实现可以使用三目运算符代替

import {defineComponent, ref} from 'vue';
export default defineComponent({
  setup() {
    const flag = ref(false);
    return () => (<>
        <div>{flag.value ? <div>东北下雪了</div> : <div>广州大太阳</div>}</div>
    </>)
  }
})

3.v-for不支持 使用map函数代替

import {defineComponent, ref} from 'vue';
export default defineComponent({
  setup() {
    const flag = ref(false);
    const data = [
        {city:'上海'},
        {city:'北京'},
        {city:'广州'},
        {city:'深圳'}
    ];
    return () => (<>
        {data.map(v=>{
            return <div>{v.city}</div>
        })}
    </>)
  }
})

4.v-bind或:传参不支持,直接使用 属性={属性值}

import {defineComponent, ref} from 'vue';
export default defineComponent({
  setup() {
    const flag = ref(false);
    const data = [
        {city:'上海'},
        {city:'北京'},
        {city:'广州'},
        {city:'深圳'}
    ];
    return () => (<>
        {data.map(v=>{
            return <div name={v.city}>{v.city}</div>
        })}
    </>)
  }
})

5.v-model支持

import {defineComponent, ref} from 'vue';
interface Props{
    name?:string
}
export default defineComponent({
  setup(props:Props,{emit}) { // 通过emit派发事件
    const v = ref<string>('');
    return () => (<>
        <input v-model={v.value} type='text'></input>
        <div>{v.value}</div>
    </>)
  }
})

Vue3 TSX组件父子组件传参

1.事件直接使用on代替@,注意不能把函数直接放进去,因为在编译阶段已经调用了

这个要通过函数柯里化的方式来解决 onClick={() =>fn()}

2.props向子组件传参数

3.emit派发函数向父组件传参

函数柯里化是指将使用多个参数的函数转化成一系列使用一个参数的函数的技术, 它返回一个新的函数, 这个新函数去处理剩余的参数

import {defineComponent, ref} from 'vue';
interface Props{
    name?:string
}
export default defineComponent({
  props:{
    name:{
        type:String,
        default:'重庆'
    }
  },
  emits:['on-click'], // 派发事件名称
  setup(props:Props,{emit}) { // 通过emit派发事件
    const data = [
        {city:'上海'},
        {city:'北京'},
        {city:'广州'},
        {city:'深圳'}
    ];
    const fn = (item:any) => {
        console.log('触发事件'+item.city)
        emit('on-click',item) // 派发事件
    }
    return () => (<>
        <div>props:{props?.name}</div>
        <hr />
        {data.map(v=>{
            return <div onClick={() =>fn(v)} name={v.city}>{v.city}</div>
        })}
    </>)
  }
})

父组件使用 

```
 <xue name="成都来了" @on-click="getItem"></xue>
```

const getItem = (item) => {
  console.log(item, '父在组件收到了');
}

插槽的用法

import {defineComponent, ref} from 'vue';
// 写一个A组件
const A = (_,{slots}) => (<>
    <div>{slots.default ? slots.default() : '默认值'}</div>
    {/* 可选链操作符 这里如果传了调用一下 */}
    <div>{slots.foo?.()}</div>
</>)
interface Props{
    name?:string
}
export default defineComponent({
  props:{
    name:{
        type:String,
        default:'重庆'
    }
  },
  setup(props:Props,{emit}) { // 通过emit派发事件
    // 插槽入参数
    const slot = {
        default:()=> (<div>我是default</div>),
        foo:()=> (<div>我是foo slots</div>)
    }
    return () => (<>
        <A v-slots={slot}></A>
        <hr />
        <div>props:{props?.name}</div>
    </>)
  }
})

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值