前言
一般在Vue2我们大都数用Element-ui去封装面包屑,现尝试使用Vue3自己封装一个面包屑,其实原理一样。
目标-效果图
功能实现
先来看看element上面的面包屑模板,基本逻辑是一样的,可以用祖孙三代来概括;
前期准备工作
- 如上图,创建三个文件,首先需了解它们的作用
- Category文件,相当于爷爷,需要使用面包屑功能组件的页面,我们将在这个文件内引入Bread和XtxBreadItem;
- Bread文件,相当于父亲,是需要包裹XtxBreadItem--儿子;
- XtxBreadItem文件,相当于儿子,里面需要放内容;
代码区域
注册全局组件
import Bread from '@/components/Bread'
import XtxBreadItem from '@/components/Bread/XtxBreadItem'
export default {
install (app) {
app.component(Bread.name, XtxBread)
app.component(XtxBreadItem.name, XtxBreadItem)
}
}
- Category文件
在这里插入代码片
<XtxBread>
<XtxBreadItem to="/">首页</XtxBreadItem>
<!-- to="/"加to表示可以点击跳转对应页面,所以要跟路由值 -->
<XtxBreadItem to="/category/1005000">活动管理</XtxBreadItem>
<XtxBreadItem>活动列表</XtxBreadItem>
<XtxBreadItem>活动详情</XtxBreadItem>
</XtxBread>
<script>
export default {
name: 'Category',
setup () {
// 面包屑连接符
provide('separator', '>')
}
}
</script>
- Bread文件
<template>
<div class='xtx-bread'>
<!-- 因为父组件中要放儿子组件,需要使用slot占位 -->
<slot></slot>
</div>
</template>
<script>
export default {
name: 'XtxBread'
}
</script>
<!-- 去掉scoped全局作用 -->
<style scoped lang="less">
.xtx-bread {
display: flex;
padding: 25px 10px;
&-item {
a {
color: #666;
transition: all 0.4s;
&:hover {
color: @xtxColor;
}
}
}
i {
font-size: 12px;
margin-left: 5px;
margin-right: 5px;
line-height: 22px;
}
}
</style>
- XtxBreadItem文件
<template>
<div class="xtx-bread-item">
<!--
如果to存在 有值 我们就渲染一个router-link标签
如果to不存在 那就渲染一个span标签,无法跳转
-->
<router-link v-if="to" :to="to"><slot /></router-link>
<span v-else><slot /></span>
<!-- 分隔符 -->
<i v-if="separator">{{ separator }}</i>
<i v-else class="iconfont icon-angle-right"></i>
</div>
</template>
<script>
import { inject } from 'vue'
export default {
name: 'XtxBreadItem',
props: {
to: {
type: String
}
},
setup () {
const separator = inject('separator')
return {
separator
}
}
}
</script>
<style lang="less" scoped>
.xtx-bread-item {
i {
margin: 0 6px;
font-size: 10px;
}
// 最后一个i隐藏,中间分隔符样式
&:nth-last-of-type(1) {
i {
display: none;
}
}
}
</style>