赞
踩
一般情况下,我们在template标签里去写静态页面模板。现在可以扩展另一种书写风格 tsx,类似react的jsx语法。vue2 的时候就已经支持jsx写法,只不过不是很友好,随着vue3对typescript的支持度增高,tsx写法越来越被接受。
npm i @vitejs/plugin-vue-jsx -D
可能会出现插件与vite版本不兼容的问题:
解决办法:添加 --force 参数,强制安装即可。
- import vueJsx from '@vitejs/plugin-vue-jsx';
- // https://vitejs.dev/config/
- export default defineConfig({
- plugins: [vueJsx()]
- })
添加以下信息在compilerOptions配置项中:
- "jsx": "preserve",
- "jsxFactory": "h",
- "jsxFragmentFactory": "Fragment",
这样就可以编写tsx文件了。
第一种编写方式,内容如下;
- export default function() {
-
- return (<div>hello world!</div>)
- }
像引入组件一样,在App.vue中 import,使用:
- import AppTsx from './App' // 后缀可省略
- ...
- <AppTsx></AppTsx>
显示结果:
第二种编写方式,该语法类似react的class component书写方式,属于Optional API。
- import { defineComponent } from 'vue'
- export default defineComponent({
- data () {
- return {
- name: "Tom",
- age: 23
- }
- },
- render () {
- return (<div>{ this.name } is { this.age } years old. </div>)
- }
- })
注意:在render函数中使用data函数定义的变量时,用的是单花括号‘{ xxx }’进行渲染。
页面效果:
- import { defineComponent } from 'vue'
- export default defineComponent({
- setup () {
- return () => (<div>Setup!</div>)
- }
-
- })
支持使用v-show的指令:
- setup () {
- const flag = false
- return () => (<div v-show={flag}>Setup!</div>)
- }
Setup!字样是正常隐藏了的。但如果给变量flag使用ref包装一下,v-show就失效了?如下:
这是因为在ts里{xx},对于响应式数据的解析不能自动.value拆包,需要手动写上.value。
不支持v-if指令:
解决:采取另一种编程思想(如js的三元表达式):
个人感觉这种结构读性较差。
不支持v-for指令:
采用数组遍历方式渲染,map()代替v-for:
v-bind 可以用 '{}' 替代:
- // App.tsc 定义接口类型
- type Props = {
- title?:string
- }
-
- export default defineComponent({
- props: {
- title:String
- },
- // setup接收props参数
- setup(props:Props) {
- return () => (
- <>
- <div> Props: { props?.title }</div>
- <hr />
- </>
- );
- }
- });
- ......
- // App.vue 传值
- <AppTsx title="我是标题"></AppTsx>

结果:
- ...
- const fun = () => {
- console.log('click!');
- }
- return () => (
- <>
- {/* <div onClick={fun()}> Props: { props?.title }</div> */}
- <div onClick={() => fun()}> Props: { props?.title }</div>
- <hr />
- </>
- );
- ...
不是以@开头的事件书写,注意{xx}不能直接调用函数,它会自动执行,需要改写为回调函数形式:onClick={() => xxx()}。
传参:
- const fun = (num:number) => {
- console.log('click!', '参数: ', num);
- }
- ...
- <div onClick={() => fun(666)}> Props: { props?.title }</div>
- ...
触发父组件事件:
- setup(props:Props, { emit }) {
- ...
- }
- ...
- const fun = (num:number) => {
- console.log('click!', '参数: ', num);
- emit('on-click', num)
- }
- // App.vue
- const getNum = (num:number) => {
- console.log('父组件接收emit: ', num);
- }
-
- ...
- <AppTsx @on-click="getNum" title="我是标题"></AppTsx>
- ...
- // 定义一个子组件
- const A = (_, { slots }) => (
- <>
- <h1>{ slots.default ? slots.default() : '默认插槽' }</h1>
- <h2>{ slots.foo?.() }</h2>
- </>
- );
- ...
-
- setup(props:Props, { emit }) {
- const slot = {
- default: () => (<div>hello - default slots</div>),
- foo: () => (<div>world - foo slots</div>),
- }
- return () => (
- <>
- <A v-slots={slot}></A>
- <hr />
- </>
- );
- }
- });
- ...

支持v-model指令:
- const v = ref<string>('')
- ...
- return () => (
- <>
- <input v-model={v.value} type="text" />
- <div>{ v.value }</div>
- </>
- );
- ...
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。