vue3+tsx 踩坑

本文章介绍vue3+tsx的使用方法。底层原理目前并没有深入了解。在项目中的配置过程就不再写了,其他文章有介绍。

https://blog.csdn.net/m0_53273062/article/details/127043544

1.vue3+tsx的几种写法

 接下来使用几个简单的代码书写几种写法。看看大家更倾向于哪一种,选择即可。目前我知道可以用一下两种方式书写。

第一种写法。

import {defineComponent} from 'vue'

export default defineComponent({

    setup(){

        // 这里使用()不用写return  如果是{}则需要写
        // 内部只能有一个跟标签,你可以使用<></>
        return ()=>(
            <div>hello tsx</div>
        )
    }


})

setup如果返回一个函数,那么这个函数就是render函数,然后render函数中属性我们的jsx代码。本人以前react开发相对tsx写法,还是比较喜欢,大家也尝试一下吧。

第二种写法

变量使用{},只要在tsx想使用任何非字符串的代码,都需要用 {} 包裹,包括数字、布尔、函数表达式等。

import {defineComponent} from 'vue'

export default defineComponent({

    setup(){
        
        // 这里主要书写你的js代码,生命周期,状态等
        // 但是需要将状态方法暴露出去

        let a = ref<string>('12')
    
        return {a}    
    },
    render(){
        return (
            <div>{this.a}<div>
        )
    }

})

2. 接收父组件传值

这里需要props进行传值类型的设置,就会映射到setup中的props,props才能拿到值。 

export default defineComponent({
  props: {
  },
  setup(props) {
    const msg = ref('hello tsx')
    const state = reactive({
      count: 1
    })

    return () => (
      <div>
        {msg.value} <span>{state.count}</span>
      </div>
    )
  }
})

 3.指令

bing指令:

vue中写法:

<A  :data="data"></A>

tsx写法:

<A data={data}></A>

 顺便写一下组件引用。vue中需要进行组件的注册,tsx写法如下:

import {defineComponent} from 'vue'
import A from '..'

export default defineComponent({

    setup(){
        return ()=>(
            <div>
                <A></A>
            </div>
        )
    }

})

v-if:

vue中

<div v-if="flag"></div>


tsx中判断则与react相似,与vue原始写法有较大差距

{
    flag?<div></div>:null
}

v-for

vue中

let data =[{},{},{}]

<div v-for="item in list" :key="item">{{item}}</div>



tsx中

{
    data?.map((item)=>{
        return <div key={item}>{item}</div> 
   })
}

v-model

v-model一般用法

vue中

<input  v-model="keyword" />

tsx中

<input v-model={keyword} />

v-model传递参数

vue2中使用v-bind.sync来实现数据的双向绑定,vue3中移除此写法,只能使用v-model,tsx写法没有多大变化,emit需要在setup第二个参数中解构。

vue2写法

<Child :title.sync="title" />

然后需要在子组件更新父组件的值,

this.$emit('update:title',newValue)


vue3写法

<Child v-model='title'/>

const emits = defineEmits(['increase']);

emits('update:modelValue',newVlaue)


如果不想使用默认名称modelValue,可以这样

<Child v-model:title='title'></Child>

const emits = defineEmits(['事件']);

emits('update:title',newVlaue)

vue3+tsx写法如下:

<Child v-model={[pageTitle,'pageTitle']}/>

传递一个数组,第一项为传递的值,第二项为子组件接收的名称

setup(props,{emit}){

emit('update:pageTitle',newValue)

}

v-model修饰符

vue写法

<input v-model.trim="keyword"/>

tsx写法


<input v-model={[keyword,['trim']]}/>



vue写法
<input v-model:title="keyword"/>

tsx写法

<input v-model:title={keyword}/>

或者
<input v-model={[keyword,'title']}/>

插槽用法

子组件写法:

import { defineComponent } from "vue";

export default defineComponent({
  name: "main",
  setup(props, { slots }) {
    return () => (
      <div>
        {slots.default ? slots.default() : null}
        {slots.title ? slots.title() : null}
      </div>
    );
  },
});

 父组件写法:

 <Main
     v-slots={{
        default:()=> <div>我是默认插槽</div>,
         title: ()=> <div>我是具名插槽</div>,
        }}
      ></Main>


或者



<Main>
    <slot name={'default'}>123</slot>
    <slot name={'title'}>123</slot>

</Main>

4.事件监听

vue写法

<div @click="handleClick"></div>


tsx写法

<div onClick={handleClick}></div>

传递参数

vue传参就是@click="handleClick(1)",但是如果tsx写法和react一样,不用回调的形式写,会导致函数直接执行,并不会点击触发事件。正确写法:onClick={()=>handleClick(1)}

5.样式文件引入

全局引入scss文件:

vite.config.ts

css: {
      preprocessorOptions: {
        scss: {
          additionalData: `@import '@/style.scss';`,
        },
      },
    },

 或者在main.ts中引入样式文件。

局部引入

第一种使用import ‘styles.scss’,这种容易导致样式污染,所以在使用时在最外层包一层,组件的独一的样式名。

注意:这种方式可以使用class或className,当在使用组件库时,className会替换到原有的类名,导致样式丢失,这时候用class,他会和原有类名合并。

第二种可以使用css module处理方案:

import styles from 'style.scss'

// 这种写法会自动给样式尾部加hash值,避免了样式污染

export default defineComponent({

    setup(){

        return ()=(
            <div class={styles.title}></div>
        )
    }
})

动态class写法

vue 写法

<div :class="{active:true}"></div>


tsx 写法  多类名写法

<div class={['box',true?'active':'']}></div>

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

成序猿@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值