vue3+tsx 踩坑
vue2中使用v-bind.sync来实现数据的双向绑定,vue3中移除此写法,只能使用v-model,tsx写法没有多大变化,emit需要在setup第二个参数中解构。注意:这种方式可以使用class或className,当在使用组件库时,className会替换到原有的类名,导致样式丢失,这时候用class,他会和原有类名合并。第一种使用import ‘styles.scss’,这种容易导致样
本文章介绍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>
更多推荐
所有评论(0)