目的: 封装一个高复用的面包屑组件,适用于多级场景。认识 render 选项和 h 函数。
参考element-ui的面包屑组件:
1.准备xtx-bread.vue组件
// 注:此组件需全局注册使用
// 基于jsx方式实现
<script>
export default {
name: 'XtxBread',
render () {
const items = this.$slots.default().filter(item => typeof item.type !== 'symbol')
const dymanicItems = []
items.forEach((item, i) => {
dymanicItems.push(item)
if (i < items.length - 1) {
dymanicItems.push(<i className="iconfont icon-angle-right"></i>)
}
})
return <div className='xtx-bread'>{dymanicItems}</div>
}
}
</script>
<style scoped lang='less'>
// 去除 scoped 属性或避免优化掉此样式(item项的样式) :deep(&-item)、:deep(i),目的:然样式作用到xtx-bread-item组件
.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>
// 注:此组件需全局注册使用
// h函数渲染实现
<script>
import { h } from 'vue'
export default {
name: 'XtxBread',
render () {
const items = this.$slots.default().filter(item => typeof item.type !== 'symbol')
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 属性或避免优化掉此样式(item项的样式) :deep(&-item)、:deep(i),目的:然样式作用到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;
}
}
</style>
2.准备xtx-bread-item.vue组件
// 注:此组件需全局注册使用
<template>
<div class="xtx-bread-item">
<RouterLink v-if="to" :to="to">
<slot />
</RouterLink>
<span v-else>
<slot />
</span>
</div>
</template>
<script>
export default {
name: 'XtxBreadItem',
props: {
to: {
type: [String, Object]
}
}
}
</script>
3.使用
<XtxBread>
<XtxBreadItem to="/">首页</XtxBreadItem>
<XtxBreadItem to="/xxxxx/id">数码</XtxBreadItem>
<XtxBreadItem >影音娱乐</XtxBreadItem>
</XtxBread>
|