在vue3中使用jsx、tsx

386 阅读1分钟

jsx

.jsx.tsx 文件同样开箱即用。JSX 的转译同样是通过 esbuild
Vue 用户应使用官方提供的 @vitejs/plugin-vue-jsx 插件,它提供了 Vue 3 特性的支持,包括 HMR,全局组件解析,指令和插槽。
$ npm i @vitejs/plugin-vue-jsx -D

- vite.config.ts
import vueJsx from '@vitejs/plugin-vue-jsx'

plugins: [
    ...
    vueJsx() // 在 vue() 后面
]

基本使用

+ TestTsx.tsx
import { defineComponent } from 'vue'
import './TestTsx.less'
// 函数式组件
// export default () => {
//   return (
//     <div class='test'>test tsx</div>
//   )
// }

// defineComponent() render Option API
// export default defineComponent({
//   // 其他配置
//   render() {
//     // 返回 jsx
//     return (
//       <div class="test">test tsx</div>
//     )
//   }
// })

// defineComponent() setup Composition API
export default defineComponent({
  // 其他配置
  setup() {
    return () => <div class="test">test tsx</div>
  }
})
    
- index.vue
import TestTsx from './TestTsx'
<TestTsx/>

Vue3中jsx/tsx特殊语法

vue独有:slot、directive、emit

指令

常用指令 v-model、v-show 用法类似,使用 {}
<input type="text" v-model={counter.value} />
    
v-if 使用条件语句或者三元表达式
<div>{ condition ? <span>A</span> : <span>B</span> }</div>

v-for使用map代替
import { defineComponent, ref } from 'vue'
export default = defineComponent({
    setup() {
        const list = ref<string[]>([])
        return () => {
            list.value.map((item, index) => {
                <p key={index}>item.name</p>
            })
        }
    }
})

插槽(v-slots)

export default defineComponent({
	setup() {
		return () => {
			<Child
				v-slots = {{
					prefix: () => <i>prefix</i>, //具名插槽
					suffix: (props: any) => <i>props.name</i>
				}}>
				默认插槽内容
			</Child>
		}
	}
})

--
<Child
	v-slots = {{
         default: () => '默认插槽'
		prefix: () => <i>prefix</i>, //具名插槽
		suffix: (props: any) => <i>props.name</i>
	}}>
</Child>
--
<Child>
    {{
         default: () => '默认插槽'
		prefix: () => <i>prefix</i>, //具名插槽
		suffix: (props: any) => <i>props.name</i>
	}}
</Child>
const Child = defineComponent({
	setup(props, {slots}) {
		return () => {
			<>
				默认插槽:{slots.default && solts.default()}
				具名插槽: {slots.prefix && slots.prefix()}
				作用域插槽:{slot.suffix && slots.suffix({
				name: props.name
				})}
			</>
		}
	}
})

emit

defineComponent({
  emits: ['click'],
  setup(props, {emit}) {
    return () => {
      <button onclick={ ()=>{ emit('click') } }>点击触发</button>
    }
  }
})

函数式组件 setup

const Login = (props: any, { slots, emit, attrs }: any) => {
  const inputValue = ref()
  const onChange = () => {
    console.log(inputValue.value)
  }
  return (
    <>
      <Input v-model:value={inputValue.value} onChange={onChange}></Input>
      Login
    </>
  )
}

Login.props = ['value']

export default Login