Vue3进阶<2>插槽在tsx 语法的使用
tsx语法
Vue3的TSX语法是一种在Vue组件中使用TypeScript编写代码的方法。TSX是JSX的扩展,它允许我们在Vue模板中使用类似于HTML的标记来描述组件的结构,tsx 语法在封装一些组件的时候有很大的用途
1.vite构建项目中使用 安装配置
bash
npm i -D @vitejs/plugin-vue-jsx
2.配置 vite.coonfig.ts
typescript
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({})],
});
3.配置tsconfig.json
json
{
"compilerOptions": {
"jsx": "preserve",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",
}
}
tsx中使用插槽
vue3中,新增了 defineComponent ,它并没有实现任何的逻辑,只是把接收的 Object 直接返回,它的存在是完全让传入的整个对象获得对应的类型,它的存在就是完全为了服务 TypeScript 而存在的。
setup 函数默认接收两个参数 1. props 2. ctx 上下文 其中包含 slots、attrs、emit 等
子组件children.tsx
typescript
import { defineComponent,reactive } from 'vue'
export default defineComponent({
setup(props, { slots }) {
const state = reactive({
name:"周杰伦",
phone: "15888888888"
})
return () => (
<div>
<p>我是子组件</p>
{/* 这是默认插槽 */}
{
slots.default ? slots.default() : null
}
{/* 这是具名插槽 */}
{
slots. sex ? slots. sex() : null
}
{/* 这是作用域插槽 */}
{
slots.fullInfo ? slots.fullInfo({ name: state.name, phone:state.phone}) : null
}
</div>
);
}
})
父组件
typescript
import Children from './components/children.tsx';
import {defineComponent} from 'vue'
export default defineComponent({
setup() {
return () => (
<div class={'box'}>
<Children>
{{
default: () => <p>年龄18</p>,
sex: () => <p>男</p>,
fullInfo(slotProps) {
return [
<p>{slotProps.name}</p>,
<p>{slotProps.phone}</p>,
];
}
}}
</Children>
</div>
);
}
})
页面效果
v-slots 指令
除了直接在组件中传递包含插槽函数的对象外,还可以通过 v-slots
指令传递,这样就可以将插槽内容单独抽取出来
typescript
import Children from './components/children.tsx';
import {defineComponent} from 'vue'
export default defineComponent({
setup() {
const slots = {
default: () => <p>年龄18</p>,
sex: () => <p>男</p>,
fullInfo(slotProps) {
return [
<p>{slotProps.name}</p>,
<p>{slotProps.phone}</p>,
];
}
}
return () => (
<div class={'box'}>
<Children v-slots={slots}/>
</div>
);
}
})
这样,结构和数据就进行了分离,看着更加干净清晰,也便于我们后期的维护。
当然,默认插槽也可以标签的形式直接写在组件里,就像这样:
typescript
return () => (
<div class={'box'}>
<p>我是父组件1</p>
<Children v-slots={slots}/>
</div>
);
页面效果
这里需要指出的是,在 Vue 官方文档中,并没有 v-slots
这个指令,我们之所以能在 TSX 中使用它是因为项目中安装了 @vitejs/plugin-vue-jsx
插件,该插件允许以 JSX 的方式来编写 Vue 代码。