一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情。
TSX
- 介绍:
vue除了使用我们的模板语法,还可以使用TSX语法。因为有过vue2中JSX的经验,相信应该很容易上手TSX的。其实都是相通的,有不同的地方下方会详细介绍~
-
安装:yarn add @vitejs/plugin-vue-jsx -D
-
文件处理 vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx' // 引入jsx
import { resolve } from 'path'
export default defineConfig({
plugins: [vue(), vueJsx()], // 使用
resolve: {
alias: {
'@': resolve('./src')
}
},
base: './', // 打包路径
server: {
port: 3000, // 服务端口号
open: true, // 服务启动时是否自动打开浏览器
cors: true // 允许跨域
}
})
在tsconfig.json 中添加一下代码
"jsx": "preserve",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",
最后,新建一个例如app.tsx的文件就可以开始使用tsx语法了
TSX语法介绍
- v-modal
1、jsx中响应数据都是用单个{};
2、使用ref,reactive不会自动解包都需要用value获取值;
import { ref } from 'vue'
let input = ref<string | number>('')
const renderDom = () => {
return (
<div>
<div>{input.value}</div>
<input type="text" v-model={input.value} />
</div>
)
}
export default renderDom;
- v-show 只需要正常定义变量即可
import { ref } from 'vue'
let flag = false;
const renderDom = () => {
return (
<div>
<div v-show={flag}>jiang</div>
<div v-show={!flag}>ciao</div>
</div>
)
}
export default renderDom;
- v-if
不支持上述写法,不过是可以利用编程思想去编写的
import { ref } from 'vue'
let flag = false;
const renderDom = () => {
return (
<div>
{flag ? <div>jiang</div> : <div>xiao</div> }
</div>
)
}
export default renderDom;
- v-for 当然也是不支持的,哈哈哈, 不过 可以采用数组循环呀~ 可能看到这 有人会想了,那我干嘛不去写react,哈哈哈~ 不过,了解一下又不吃亏 嘻嘻~
import { ref } from 'vue'
let arr = ['j','x','x','j']
const renderDom = () => {
return (
<div>
{arr.map(item => {
return(<div>hah{item}</div>)
})}
</div>
)
}
export default renderDom
- 事件绑定,也是不支持的,所以直接来上代码。以点击事件以及传值为例,与vue的模板语法都略有不同。
import { ref } from 'vue'
let arr = ['j','x','x','j']
const renderDom = () => {
return (
<div>
{arr.map(item => {
return(<div onClick={handleClick.bind(this, item)}>hah{item}</div>) // 通过bind进行传值
})}
</div>
)
}
const handleClick = (item:string) => {
console.log('点击了' + item);
}
export default renderDom;
当然这里也是不支持修饰符的,所以需要我们去使用原生方法去解决。
- props,ctx(ctx.emit)
// tsx文件
let arr = ['j','x','x','j'];
type Props = {
title: string
}
const renderDom = (props: Props, ctx:any) => {
return (
<div>
<div>{props.title}</div>
{arr.map(item => {
return(<div onClick={handleClick.bind(this, ctx)}>hah{item}</div>)
})}
</div>
)
}
const handleClick = (ctx:any) => {
ctx.emit('handle-click', 'jiang')
}
export default renderDom;
// 父组件
<template>
<div class="home">
<render-dom @handle-click="clicked" title="jiang"></render-dom>
</div>
</template>
<script setup lang="ts">
import renderDom from '../app';
const clicked = (info:any) => {
console.log('收到',info)
}
</script>
v-model的其他用法
-
介绍
v-modal其实也可以应用在组件当中,它其实是通过事件的接收和派发组合在一起的。
-
改变
1、.sync修饰符和组件的model选项已经去掉;
2、可以支持多个v-model进行双向数据绑定;
3、可以支持自定义修饰符;
-
注意: v-model在vue3中是破坏型更新;
多个v-model进行双向数据绑定
-
代码示例:
完成简易dialog弹窗组件。废话不多说,直接上代码~
子组件
<template>
<div class="dialog" v-if="isModal">
<div class="header">
<div>标题{{title}}</div>
<div @click="close">x</div>
</div>
<div class="cotent">内容</div>
</div>
</template>
<script setup lang="ts">
type Props = {
isModal: boolean,
title: string,
}
defineProps<Props>(); // 接收父组件传过来的值
const emit = defineEmits(['update:isModal', 'update:title']); //子组件将父组件所需要的值进行派发
const close = () => {
emit('update:isModal', false)
emit('update:title', 'xiao')
}
</script>
父组件
此时的父组件可以进行多个双向数据绑定~
<template>
<div class="home">
<button @click="flag = !flag">{{flag ? '开' : '关'}}</button>
<div>标题:{{title}}</div>
<Dialog v-model:isModal="flag" v-model:title="title"></Dialog>
</div>
</template
<script setup lang="ts">
import Dialog from '../components/dialog.vue';
import { ref } from 'vue'
let flag = ref<boolean>(true);
let title = ref<string>('jiangxx')
</script>
自定义修饰符
在vue2时候官方给我们很多修饰符,例如v-model.number、v-model.trim等。在vue3中我们可以通过一个包含空对象的modelModifiers关键字进行构建自定义修饰符~
注意:当多绑定多个v-model时给其中一个添加自定义修饰符时,例如v-model:title = "title" 此时包含空对象的自定义关键字名为titleModifiers,也就是说Modifiers前面的名称要和v-model:后面的保持一致。至于,用法都是一样的
此处基于上述代码进行添加
// 父组件中添加相应的自定义修饰符v-model.jiang
<Dialog v-model:isModal="flag" v-model:title="title" v-model.jiang="flag"></Dialog>
// 子组件
<script setup lang="ts">
type Props = {
isModal: boolean,
title: string,
modelModifiers?: { // 通过此关键字添加修饰符
jiang: boolean
}
}
const data = defineProps<Props>();
const emit = defineEmits(['update:isModal', 'update:title'])
const close = () => {
// 可以通过关键字进行逻辑操作
if (data.modelModifiers?.jiang) {
emit('update:title', 'xiao')
} else {
emit('update:title', 'xue')
}
emit('update:isModal', false)
}
</script>
vue3虽然,有些东西没有了,但是用起来更加灵活也更加得心应手。JSX也更加的方便我们封装高级组件,感兴趣的小伙伴就抓紧入坑吧~ 用它~