下载 @vitejs/plugin-vue-jsx

pnpm add @vitejs/plugin-vue-jsx

配置

vite.config.ts

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";

export default defineConfig({
	plugins: [vue(), vueJsx()],
});

tsconfig.json
当使用 TSX 语法时,确保在 tsconfig.json 中配置了 “jsx”: “preserve”,这样的 TypeScript 就能保证 Vue JSX 语法转换过程中的完整性。

从 Vue 3.4 开始,Vue 不再隐式注册全局 JSX 命名空间。要指示 TypeScript 使用 Vue 的 JSX 类型定义,请确保在你的 tsconfig.json 中包含以下内容:

{
	"compilerOptions": {
		"jsxImportSource": "vue",
		"jsx": "preserve",
	}
}

使用

  • 函数式组件使用

.tsx 文件

export default () => {
	return (
		<>
			<div>test</div>
		</>
	);
};
  • defineComponent + setup 使用
import { defineComponent } from "vue";

export default defineComponent({
	setup(props, { slots, emit }) {
		return () => {
			return <div>demo</div>;
		};
	},
});

使用样式

  • 行内样式不变
export default () => {
	return (
		<>
			<div style="font-size: 30px;">num 值:{num.value}</div>
		</>
	);
};
  • 引入外部 css 文件
import "./base.css";

export default () => {
	return (
		<div>
			<div class="blue">blue</div>
		</div>
	);
};
  • css module
import styles from "./children.module.css";

export default () => {
	return (
		<div>
			<div class={styles.red}>red</div>
		</div>
	);
};

在这里插入图片描述

使用 ref 等变量

在 JSX 表达式中,使用大括号来嵌入动态值
在 JSX 表达式中,ref 不能自动解包 需要 .value

import { ref } from "vue";

const num = ref(1);

export default () => {
	return (
		<>
			<div>num 值:{num.value}</div>
		</>
	);
};

v-on 事件绑定写法

以 on 开头,并跟着大写字母的 props 会被当作事件监听器。比如,onClick 与模板中的 @click 等价。

import { ref } from "vue";

const num = ref(1);
// 2 直接写事件名 handleAdd
// function handleAdd() {
// 	num.value += 1;
// }

// 3 传递参数
function handleAdd(n: number, e: MouseEvent) {
	console.log("11", n, e.x);
	num.value += n;
}
export default () => {
	return (
		<>
			<div>num 值:{num.value}</div>
			{/* 1 内联写法 */}
			{/* <button
				onClick={() => {
					num.value += 1;
				}}
			>
				修改 num + 1
			</button> */}
			{/* 2 直接写事件名 handleAdd  */}
			{/* <button onClick={handleAdd}>修改 num + 1</button> */}

			{/* 3 传递参数 */}
			<button onClick={(e) => handleAdd(2, e)}>修改 num + 2</button>
		</>
	);
};

事件修饰符

对于 .passive、.capture 和 .once 事件修饰符,可以使用驼峰写法将他们拼接在事件名后面:

<button onClickOnce={handleAdd}>修改 num + 1</button>

v-if

import { ref } from "vue";

const flag = ref(true);

export default () => {
	return <>{flag.value ? <div>真</div> : <p>假</p>}</>;
};

v-for

const data = [
	{
		name: "张三",
	},
	{
		name: "李四",
	},
];

export default () => {
	return (
		<ul>
			{data.map((item) => {
				return <li>{item.name}</li>;
			})}
		</ul>
	);
};

组件

src/components/tsx-children.tsx

export default () => {
	return <div>tsx-children</div>;
};

使用
src/components/tsx-father.tsx

import TsxChildren from "./tsx-children";

export default () => {
	return (
		<div>
			<TsxChildren />
		</div>
	);
};

在 setup 中使用

import TsxChildren from "./tsx-children";

export default {
	setup() {
		return () => {
			return (
				<>
					<TsxChildren />
				</>
			);
		};
	},
};

插槽 slot

  • 定义默认插槽

src/components/tsx-children.tsx

export default (props, { slots }) => {
	return (
		<>
			<div class="default">{slots.default?.()}</div>
		</>
	);
};

使用
src/components/tsx-father.tsx

import TsxChildren from "./tsx-children";

export default () => {
	return (
		<div>
			<TsxChildren>
				{{
					default: () => <p>我是默认插槽的内容</p>,
				}}
			</TsxChildren>
		</div>
	);
};
  • 定义具名插槽,传递值

src/components/tsx-children.tsx

export default (props, { slots }) => {
	return (
		<>
			<div class="default">{slots.default?.()}</div>
			{/* 传递 msg  */}
			<div class="footer">{slots.footer?.({ msg: "footer 插槽" })}</div>
		</>
	);
};

使用
src/components/tsx-father.tsx

import TsxChildren from "./tsx-children";

export default () => {
	return (
		<div>
			<TsxChildren>
				{{
					default: () => <p>我是默认插槽的内容</p>,
					// 解构 msg 值,使用
					footer: ({ msg }) => <p>我是-{msg}-的内容</p>,
				}}
			</TsxChildren>
		</div>
	);
};
Logo

前往低代码交流专区

更多推荐