封装 WelcomeLayout 组件
目的:消除重复
四个页面只有图片、文字不同,布局结构是一致的
重构前
// src/components/welcome/First.tsx
import { defineComponent } from 'vue';
import s from './First.module.scss';
import pig from '../../assets/icons/pig.svg';
import { RouterLink } from 'vue-router';
export const First = defineComponent({
setup: (props, context) => {
return () => (
<div class={s.wrapper}>
<div class={s.card}>
<img src={pig} />
<h2>会挣钱<br/>还要会省钱</h2>
</div>
<div class={s.actions}>
<RouterLink class={s.fake} to="/start" >跳过</RouterLink>
<RouterLink to="/welcome/2" >下一页</RouterLink>
<RouterLink to="/start" >跳过</RouterLink>
</div>
</div>
)
}
})
重构后
将布局封装为一个组件,内容通过插槽来传入
// src/components/welcome/WelcomeLayout.tsx
import { defineComponent } from 'vue';
import s from './First.module.scss';
export const WelcomeLayout = defineComponent({
setup: (props, context) => {
const {slots} = context
return () => (
<div class={s.wrapper}>
<div class={s.card}>
{slots.icon?.()}
{slots.title?.()}
</div>
<div class={s.actions}>
{slots.buttons?.()}
</div>
</div>
)
}
})
/* 还可以写成函数组件形式
import { FunctionalComponent } from 'vue';
import s from './WelcomeLayout.module.scss';
export const WelcomeLayout: FunctionalComponent = (props, context) => {
const { slots: { icon, title, buttons } } = context
return (
<div class={s.wrapper}>
<div class={s.card}>
{icon?.()}
{title?.()}
</div>
<div class={s.actions}>
{buttons?.()}
</div>
</div>
)
}
*/
// src/components/welcome/First.tsx
import { defineComponent } from 'vue';
import s from './First.module.scss';
import pig from '../../assets/icons/pig.svg';
import { WelcomeLayout } from './WelcomeLayout'
import { RouterLink } from 'vue-router';
export const First = defineComponent({
setup: (props, context) => {
const slots = {
icon: () => <img src={pig} />,
title: () => <h2>会挣钱<br />还会省钱</h2>,
buttons: () => <>
<RouterLink class={s.fake} to="/start" >跳过</RouterLink>
<RouterLink to="/welcome/2" >下一页</RouterLink>
<RouterLink to="/start" >跳过</RouterLink>
</>
}
return () => (
<WelcomeLayout v-slots={slots}></WelcomeLayout>
/* 也可以不用 v-slot 这样写
<WelcomeLayout>
{{
icon: () => <img src={pig} />,
title: () => <h2>会挣钱<br />还会省钱</h2>,
buttons: () => <>
<RouterLink class={s.fake} to="/start" >跳过</RouterLink>
<RouterLink to="/welcome/2" >下一页</RouterLink>
<RouterLink to="/start" >跳过</RouterLink>
</>
}}
</WelcomeLayout>
*/
)
}
/* 还可以写成函数组件形式
export const First: FunctionalComponent = () => {
return <WelcomeLayout>{{
icon: () => <img src={pig} />,
title: () => <h2>会挣钱<br />还会省钱</h2>,
buttons: () => <>
<RouterLink class={s.fake} to="/start" >跳过</RouterLink>
<RouterLink to="/welcome/2" >下一页</RouterLink>
<RouterLink to="/start" >跳过</RouterLink>
</>
}}</WelcomeLayout>
}
First.displayName = 'First'
*/
})