TSX优势
代码效验、代码提示、错误提示
支持ts里直接写标签 及 组件
还可以将组件写在函数里,结合一下动态值,然后调用函数,实现组件参数的复杂计算
//main.ts中将
import App from './App.vue'
改为:
import App from './App'
实现app.vue,用更直观的js写法,vue的h函数
// App.vue 改为 App.ts
import { createApp, defineComponent, h, reactive, ref ,PropType } from 'vue'
export default defineComponent({
setup() {
const state = reactive({
name: 'ax:',
})
const numberRef = ref("bx:")
setInterval(() => {
state.name += 'a'
numberRef.value += 'b'
}, 2000)
return () => {
const number = numberRef.value //Ref的变化会引起return 函数的重新执行,所以才会重新渲染节点,让值有更新
return h('div', { id: 'app' }, [h('p', state.name), h('p', number)])
}
},
})
JSX 编中写html标签
jsx中写html标签是如何一步步进化衍变的
1、渲染函数 render
//main.ts
import { createApp, defineComponent, createVNode,h } from "vue";
const App2 = defineComponent({
render() {
return (
//h('div', { id: 'app' }),
createVNode('div', { id: 'app' }),
[
h('img', {
alt: 'Vue logo'
})
]
)
},
})
createApp(App2).mount("#app");
h函数只是createVNode的简单封装,所以把h函数替换为createVNode也是一样的
setup中使用H函数
<template>
<diy />
</template>
<script setup>
import { ref,h } from 'vue'
const msg = ref('abc')
const diy = () => h('div',msg.value);
</script>
2、Babel 插件
如果你写了很多 render 函数,可能会觉得这样的代码写起来很痛苦,特别是对应的模板如此简单的情况下。
这就是为什么会有一个 Babel 插件,用于在 Vue 中使用 JSX 语法,它可以让我们回到更接近于模板的语法上。
render() {
return <div>Vue 3.0</div>;
},
vue2有官方的babel插件
安装: npm install @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props
vue3没有官方的,有阿里出的 vuejs/jsx-next
安装: npm install @vue/babel-plugin-jsx -D
还需要在babel.config.js文件中配置plugins: ["@vue/babel-plugin-jsx"]
//App.tsx
import { defineComponent} from 'vue'
export default defineComponent({
setup() {
return () => {
return <div>asd</div>;
}
},
})
App.vue改为App.jsx需要安装扩展,不然会报错!
https://github.com/vuejs/jsx-next
npm install @vue/babel-plugin-jsx -D
新建一个 .babelrc 文件,内容如下
{
"plugins": ["@vue/babel-plugin-jsx"]
}
最新版vue3不安装这个扩展,改为import App from './App'
也是能正常运行App.tsx的
//App.vue.tsx
import { createApp, defineComponent, h, reactive, ref ,PropType } from 'vue'
import HelloWorld from './components/HelloWorld'
const img = require('./assets/logo.png') // eslint-disable-line
//setup return里可以直接放组件,也可以提出来放函数里计算后传参并返回组件
//cfg:any,在组件处不会报错,因为any代表任意,那config也是能适用的
function renderHelloWorld(num: number,cfg:Config) {
return <HelloWorld age={num} msg="abc" config={cfg} />
}
//所以为了判断类型,这里也要有一个config接口
interface Config {
name: string,
num: number
}
export default defineComponent({
setup() {
const state = reactive({
name: 'ax:',
})
const cfg: Config={
name:"abc",
num:321
}
const numberRef = ref("bx:")
setInterval(() => {
state.name += 'a'
numberRef.value += 'b'
}, 2000)
return () => {
const number = numberRef.value
return (
<div id="app">
<img src={img} alt="Vue logo" />
<p>{state.name}</p>
<p>{number}</p>
<input type="text" v-model={state.name} />
{renderHelloWorld(12,cfg)}
</div>
)
}
},
})
//HelloWorld.tsx
import { defineComponent, PropType } from "vue";
interface Config {
name: string,
num:number
}
const PropsType = {
msg: String,
config: {
type: Object as PropType<Config>,
required: true,
},
age: {
type: Number,
required: true,
},
} as const;
export default defineComponent({
props: PropsType,
setup(props) {
return () => <div>abc:{props.age}--{props.config.name}++</div>;
},
});
组件如果是vue文件,那编辑器不会有代码提示和代码检测。组件为tsx文件则可以
注意:
在vscode中ts项目引入的库,如vue有红色底线,但运行又没问题问题,那就是vscode自身的bug
解决办法:File -> Close folder然后File -> Open Folder 再次打开项目文件夹,错误就会消失
网友评论