Appearance
babel 插件
vIfTransformPlugin
- 让 react 的 v-if 语法支持在 jsx 中使用
插件实现
js
// plugins/vIfTransformPlugin.js
import { types } from "@babel/core";
function vIfTransformPlugin() {
return {
visitor: {
JSXElement(path) {
const { node } = path;
const { openingElement } = node;
const { attributes } = openingElement;
const attrIndex = attributes.findIndex(
(attr) => attr.name?.name === "v-if"
);
if (attrIndex === -1) return;
// 获取条件表达式
const condition = attributes[attrIndex].value?.expression;
// 移除属性
attributes.splice(attrIndex, 1);
// 替换为条件渲染:{condition && <div />}
path.replaceWith(
types.jsxExpressionContainer(
types.logicalExpression("&&", condition, node)
)
);
},
},
};
}
export default vIfTransformPlugin;
引用插件
js
// vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import vIfElsePlugin from "./plugins/vIfTransformPlugin";
export default defineConfig({
plugins: [
react({
babel: {
plugins: [vIfElsePlugin], // 应用自定义 Babel 插件
},
}),
],
});
使用
jsx
import { useState } from "react";
function App() {
let [num, setNum] = useState(0);
return (
<>
<button onClick={() => setNum((num) => ++num)}>click{num}</button>
<div v-if={num == 0}>aa{num}</div>
<div v-if={num == 1}>bb{num}</div>
<div v-if={num >= 2}>cc{num}</div>
</>
);
}
export default App;