vue3手搓面包屑

126 阅读1分钟
前段时间需要一个面包屑的组件,想着手动封装一下

大致思路就是使用到了solt,封装为类似于elment那种面包屑的组件,但是需要比较灵活的
首先是需要有两个组件来完成,一个bread和bread-item,

bread组件
<template>
  <div class='bread'>
    <slot />   //这里插槽插入bread-item内容
  </div>
</template>

<script>
export default {
  name: 'Bread'
}
</script>
<!-- 去掉scoped全局作用 -->
<style lang='less'>
bread-item组件
<template>
  <div class="bread-item">
    <RouterLink v-if="to" :to="to"><slot /></RouterLink>//判断有没有传入跳转链接
    <span v-else><slot /></span>
    <i class="iconfont icon-angle-right"></i>
  </div>
</template>
<script>
export default {
  name: 'BreadItem',
  props: {
    to: {
      type: [String, Object]
    }
  }
}
</script>

这样封装号以后注册组件就可以直接使用了

     <Bread>
        <BreadItem to="/">首页</BreadItem>
        <BreadItem to="/category/1005000">电器</BreadItem>
        <BreadItem >空调</BreadItem>
      </Bread>

这样效果就出来传入:to可直接进行跳转,不传入只坐展示

Snipaste_2023-05-17_10-19-07.png

但是elment的是没有最后一个箭头图标的,

Snipaste_2023-05-17_10-20-44.png

这里原本想着是直接用css进行解决,但又想有没有更好的方法,就想到了vue3的render函数, 组件的模板可以直接使用render函数代替template选项。通过render函数,我们可以更加灵活地控制组件的渲染结果,实现更加复杂的交互效果,我们可以在其中使用JSX或h函数来生成虚拟DOM,下面是具体代码

<script>
import { h } from "vue";
export default {
  name: "Bread",
  render() {
    // 用法
    // 1. template 标签去除,单文件组件
    // 2. 返回值就是组件内容
    // 3. vue2.0 的h函数传参进来的,vue3.0 的h函数导入进来
    // render:h=>{
    //   return ''
    // }
    // 4. h 第一个参数 标签名字  第二个参数 标签属性对象  第三个参数 子节点
    // 需求
    // 1. 创建bread父容器
    // 2. 获取默认插槽内容
    // 3. 去除bread-item组件的i标签,因该由render函数来组织
    // 4. 遍历插槽中的item,得到一个动态创建的节点,最后一个item不加i标签
    // 5. 把动态创建的节点渲染再xtx-bread标签中
    // 这个是获取到插槽内的dom
    const items = this.$slots.default();
    // console.log(items);
    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>

这样的话使用效果直接就可以出来了,不用担心组件的箭头图标问题了

image.png