经过前两次的铺垫,想必大家多面包屑组件的封装也有了一定的了解,今天,我们就来一个终极版,完美实现面包屑组件的多级展示问题,这里我们使用到了render函数
同样我们需要两个组件:bread组件和 bread-item 组件
bread-item组件
<template>
<div class="xtx-bread-item">
<RouterLink v-if="to" :to="to"><slot /></RouterLink>
<span v-else><slot /></span>
</div>
</template>
bread组件
<script>
import { h } from 'vue'
export default {
name: 'XtxBread',
render () {
// 用法
// 1. template 标签去除,单文件组件
// 2. 返回值就是组件内容
// 3. vue2.0 的h函数传参进来的,vue3.0 的h函数导入进来
// 4. h 第一个参数 标签名字 第二个参数 标签属性对象 第三个参数 子节点
// 需求
// 1. 创建xtx-bread父容器
// 2. 获取默认插槽内容
// 3. 去除xtx-bread-item组件的i标签,因该由render函数来组织
// 4. 遍历插槽中的item,得到一个动态创建的节点,最后一个item不加i标签
// 5. 把动态创建的节点渲染再xtx-bread标签中
const items = this.$slots.default()
const dymanicItems = []
items.forEach((item, i) => {
dymanicItems.push(item)
if (i < (items.length - 1)) {
dymanicItems.push(h('i', { class: 'iconfont icon-angle-right' }))
}
})
return h('div', { class: 'xtx-bread' }, dymanicItems)
}
}
</script>
<style lang='less'>
// 去除 scoped 属性,目的:然样式作用到xtx-bread-item组件
.xtx-bread{
display: flex;
padding: 25px 10px;
&-item {
a {
color: #666;
transition: all .4s;
&:hover {
color: @xtxColor;
}
}
}
i {
font-size: 12px;
margin-left: 5px;
margin-right: 5px;
line-height: 22px;
// 样式的方式,不合理
// &:last-child {
// display: none;
// }
}
}
</style>
使用代码:
<!-- 面包屑 -->
<XtxBread>
<XtxBreadItem to="/">首页</XtxBreadItem>
<XtxBreadItem to="/category/1005000">电器</XtxBreadItem>
<XtxBreadItem >空调</XtxBreadItem>
</XtxBread>
这样我们就实现了面包屑的动态多级展示
最终效果:
最后,在给大家分享一个高级的优化代码的方法,就是基于jsx方式实现
<script>
export default {
name: 'XtxBread',
render() {
// 去掉注释
const slotContent = this.$slots.default().filter(item => item.type.name === 'XtxBreadItem')
console.log(slotContent)
// 浅拷贝一下
const children = []
slotContent.forEach((item, i) => {
// 添加单个面包屑组件
children.push(item)
if (i < slotContent.length - 1) {
children.push(<i className="iconfont icon-angle-right"></i>)
}
})
return <div className="xtx-bread">{children}</div>
}
}
</script>
<style scoped lang="less">
.xtx-bread {
display: flex;
padding: 25px 10px;
:deep(&-item) {
a {
color: #666;
transition: all 0.4s;
&:hover {
color: @xtxColor;
}
}
}
:deep(i) {
font-size: 12px;
margin-left: 5px;
margin-right: 5px;
line-height: 22px;
}
}
</style>
注:这就是最终相对优化的代码,同时也解决了再组件插槽写注释会被解析的问题,