1.jsx文件书写格式
jsx内部写<router-view></router-view> 不能生效, 还是要写在vue文件里
写法一: 类似setup script式, 没法传入props
element-plus 在jsx中需要手动引入组件
// Main.jsx
import { defineComponent, ref } from 'vue';
import { ElButton } from "element-plus";
export default defineComponent(() => {
// 传入 setup 函数
const status = ref(1)
const render = () => {
return <ElButton
size={"small"}
color={status === 1 ? "#4bb04e" : "#f99724"}
style={{ color: "#fff" }}
>
{status === 1 ? "已回访" : "未回访"}
</ElButton>
};
return render;
});
写法二: 选项式
// Main.jsx
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'MainPage',
// 传入组件配置
props: { name: { type: String, default: '66' } },
emits: ['update:modelValue'],
setup(props, { slots, emit, attrs })) {
const handleClick = (value) => {
emit('update:modelValue', value)
}
const render = () => {
return <p>child {props.name}</p>;
};
return render;
},
});
写法三: 函数式
只能作为组件渲染用, 标签用动态变量会失去响应式
// Main.jsx
function MainPage(props, { slots, emit, attrs }) {
return <p>child {props.name}</p>;
}
export default MainPage;
调用组件
import Main from '../**/Main';
2. 配置项
安装
pnpm add @vitejs/plugin-vue-jsx vite配置
// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx()],
})
tsconfig配置
// tsconfig.json
{
"compilerOptions": {
"jsx": "preserve",
}
}
3. 插入样式
引入外联样式
// Main.jsx
import './Main.scss';
function MainPage(props, { slots, emit, attrs }) {
return (
<div>
// 普通类名
<p class="title">child {props.name}</p>;
// 动态类名
<div class={class={activeIndex.value ? 'active nav-item' : 'nav-item'}> </div>
</div>
)
}
export default MainPage;
css module方式引入(防止样式污染)
-
- 添加配置
// vite.config.js 或者 vue.config.js 添加css配置
css: {
// css预处理器
preprocessorOptions: {
requireModuleExtension: true,
},
},
-
- 修改scss文件名
test.module.scss
-
- 引入方式
import { defineComponent } from 'vue'
import styles from './test.module.scss'
export default defineComponent({
setup () {
return () => {
return <div class={styles.test}>
</div>
}
}
})
-
- 解决ts引入scss报错
// **shims-vue.d.ts**
declare module "*.scss" {
const classes: { readonly [key: string]: string };
export default classes;
}
-
- ts类名自动提示工具 a. 安装依赖
npm install typescript-plugin-css-modules --save-dev
b.tsconfig.json添加配置
"plugins": [{"name": "typescript-plugin-css-modules"}]
c. 在项目根目录上创建.vscode文件夹,添加settings.json文件
// settings.json
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
4. 基本语法
- 动态变量
{} 是jsx的万能的用法,里面可以写js的表达式,循环逻辑操作等等
<div>{age}</div> //没有" "包裹,统一都是{}
- v-if
// 使用&&运算
{show && <span>test vif</span>}
// 三元表达式
<div>{ok.value ? <div>yes</div> : <span>no</span>}</div>
// if条件函数
const vif=()=>{
if(show) {
return <span>test vif</span>
}
return <span>test velse</span>
}
return ()=>(
<>
vif() //if条件函数
</>
)
- v-show
<span v-show={show.value}> test vshow</span>
- v-for
<nav class="main-nav">
{tabs.value.map((item) => {
return <span key={item.id} class="nav-tab">{item.value}</span>;
})}
</nav>
- v-on
使用on+大驼峰形式(
首字母大写), 方法名需要使用 {} 包裹起来无自定义参数的函数不需要带()结尾
jsx需要借助withModifiers,实现
.self,.stop等修饰符的效果
// 标签内部写方法
<span
onClick={(e) => {
console.log(e);
}}
class="nav-tab"
>
{item}
</span>
// 方法写在外面
function handleClick (e) {
console.log(e)
}
<span
onClick={handleClick}
class="nav-tab"
>
{item}
</span>
// 事件传参
function handleClick (item) {
console.log(item)
}
<span
onClick={() => handleClick(item)}
class="nav-tab"
>
{item}
</span>
//withModifiers包裹vue修饰符
<div onClick={withModifiers(handleClick, ["stop"])}>{item}</div>
- ref绑定
ref分两种,一种是指的ref()定义的双向绑定变量,另外则是 绑定在Dom标签的ref引用
ref()定义的双向绑定变量, 加 .value
Dom标签的ref引用, 用ref(null)变量, 不需要加 .value
const divRef=ref(null);
const age= ref(0);
return ()=>
(
<div ref={divRef} > //Dom标签的ref引用
<span>{age.value}</span> //ref()双向绑定变量
</div>
)
- v-model 语法
组件只有一个v-model时,使用v-model语法
组件只有多个v-model时,可以使用v-model:xx语法
//一个v-model
<tz-input v-model={age} />
//多个v-model (v-model:修饰符)
<tz-input v-model:foo={age} v-model:bar={gender} />
- 插槽 v-slots
//方法一
const App = {
setup() {
const slots = {
default: () => <div>A</div>, //默认插槽
bar: () => <span>B</span>, //具名插槽
};
return () => <A v-slots={slots} />;
},
};
//方法二
const App = {
setup() {
return () => (
<>
<A>
{{
default: () => <div>A</div>, //此方法 默认default不能少
bar: () => <span>B</span>, //具名插槽
}}
</A>
<B>{() => "foo"}</B>
</>
);
},
};
v-slots语法 element-plus中table组件scope使用如下
// jsx写法一
<el-table-column
fixed="right"
label="操作"
width="150"
v-slots={{
default: (scope: any) => (
<el-button size="small" onClick={() => handleEdit(scope.row)}>
Edit
</el-button>
),
}}
></el-table-column>
jsx写法二
<el-table-column fixed="right" label="操作" width="150">
{{
default: (scope: any) => (
<el-button size="small" onClick={() => handleEdit(scope.row)}>
Edit
</el-button>
),
}}
</el-table-column>
- 指令的修饰符
指令使用下划线 ,比如v-loading_fullscreen_lock
<span v-loading_fullscreen_lock={isLoading}> loading </span>
- jsx里面引入其他组件
import { defineComponent, ref } from 'vue';
import OrderType from './orderType';
export default defineComponent({
setup() {
const render = () => (
<div>
<OrderType />
</div>
);
return render;
},
});