Vue3电商项目实战-分类模块1【01-顶级类目-面包屑组件-初级、02-顶级类目-面包屑组件-高级】


01-顶级类目-面包屑组件-初级

目的: 封装一个简易的面包屑组件,适用于两级场景。

大致步骤:

  • 准备静态的 xtx-bread.vue 组件
  • 定义 props 暴露 parentPath parentName 属性,默认插槽,动态渲染组件
  • library/index.js 注册组件,使用验证效果。

落的代码:

  • 基础结构 src/components/library/xtx-bread.vue
<template>
  <div class='xtx-bread'>
    <div class="xtx-bread-item">
      <RouterLink to="/">首页</RouterLink>
    </div>
    <i class="iconfont icon-angle-right"></i>
    <div class="xtx-bread-item">
      <RouterLink to="/category/10000">电器</RouterLink>
    </div>
    <i class="iconfont icon-angle-right"></i>
    <div class="xtx-bread-item">
      <span>空调</span>
    </div>
  </div>
</template>

<script>
export default {
  name: 'XtxBread'
}
</script>

<style scoped lang='less'>
.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>
  • 定义props进行渲染 src/components/library/xtx-bread.vue
<template>
  <div class='xtx-bread'>
    <div class="xtx-bread-item">
      <RouterLink to="/">首页</RouterLink>
    </div>
    <i class="iconfont icon-angle-right"></i>
+    <div class="xtx-bread-item" v-if="parentName">
+      <RouterLink v-if="parentPath" :to="parentPath">{{parentName}}</RouterLink>
+      <span v-else>{{parentName}}</span>
+    </div>
+    <i v-if="parentName" class="iconfont icon-angle-right"></i>
    <div class="xtx-bread-item">
+      <span><slot /></span>
    </div>
  </div>
</template>

<script>
export default {
  name: 'XtxBread',
+  props: {
+    parentName: {
+      type: String,
+      default: ''
+    },
+    parentPath: {
+      type: String,
+      default: ''
+    }
+  }
}
</script>
  • 注册使用 src/components/library/index.js
+import 'XtxBread' from './xtx-bread.vue'

export default {
  install (app) {
+      app.component(XtxBread.name, XtxBread)

使用: <XtxBread parentPath="/category/1005000" parentName="电器">空调</XtxBread>

总结: 采用基本的封装手法,灵活度不是很高。

02-顶级类目-面包屑组件-高级

目的: 封装一个高复用的面包屑组件,适用于多级场景。认识 render 选项和 h 函数。

参考element-ui的面包屑组件:

在这里插入图片描述

大致步骤:

  • 使用插槽和封装选项组件完成面包屑组件基本功能,但是最后一项多一个图标。
  • 学习 render 选项,h 函数 的基本使用。
  • 通过 render 渲染,h 函数封装面包屑功能。

落的代码:

  • 我们需要两个组件,xtx-breadxtx-bread-item 才能完成动态展示。
    定义单项面包屑组件 src/components/library/xtx-bread-item.vue
<template>
  <div class="xtx-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: 'XtxBreadItem',
  props: {
    to: {
      type: [String, Object]
    }
  }
}
</script>
  • library/index.js注册
+import 'XtxBreadItem' from './xtx-bread-item.vue'
export default {
  install (app) {
+      app.component(XtxBreadItem.name, XtxBread)
  • 过渡版,你发现结构缺少风格图标,如果在item中加上话都会有图标,但是最后一个是不需要的。
<template>
  <div class='xtx-bread'>
    <slot />
  </div>
</template>

<script>
export default {
  name: 'XtxBread'
}
</script>
<!-- 去掉scoped全局作用 -->
<style lang='less'>
      <!-- 面包屑 -->
      <XtxBread>
        <XtxBreadItem to="/">首页</XtxBreadItem>
        <XtxBreadItem to="/category/1005000">电器</XtxBreadItem>
        <XtxBreadItem >空调</XtxBreadItem>
      </XtxBread>
  • 终极版,使用render函数自己进行拼接创建。
    createElement render render选项与h函数

  • 指定组件显示的内容:new Vue({选项})

    • el 选项,通过一个选择器找到容器,容器内容就是组件内容
    • template 选项,<div>组件内容</div> 作为组件内容
    • render选项,它是一个函数,函数回默认传人createElement的函数(h),这个函数用来创建结构,再render函数返回渲染为组件内容。它的优先级更高。
//import App from './App.vue'
//new Vue({
//    render:h=>h(App)
//}).mount('#app')
// h() =====>  createElement()
// h(App) =====>  根据APP组件创建html结构
// render的返回值就是html结构,渲染到#app容器
// h() 函数参数,1.节点名称  2. 属性|数据 是对象  3. 子节点

xtx-bread-item.vue

<template>
  <div class="xtx-bread-item">
    <RouterLink v-if="to" :to="to"><slot /></RouterLink>
    <span v-else><slot /></span>
-    <i class="iconfont icon-angle-right"></i>
  </div>
</template>

xtx-bread.vue

<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;
  // ul li:last-child {}
  // 先找到父元素,找到所有的子元素,找到最后一个,判断是不是LI,是就是选中,不是就是无效选择器
  // ul li:last-of-type {}
  // 先找到父元素,找到所有的类型为li的元素,选中最后一个
  &-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>
  • 总结,一下知识点
    • render 是vue提供的一个渲染函数,优先级大于el,template等选项,用来提供组件结构。
    • 注意:
      • vue2.0 render函数提供h(createElement)函数用来创建节点
      • vue3.0 h(createElement)函数有 vue 直接提供,需要按需导入
    • this.$slots.default() 获取默认插槽的node结构,按照要求拼接结构。
    • h函数的传参 tag 标签名|组件名称, props 标签属性|组件属性, node 子节点|多个节点
    • 具体参考 render
  • 注意:不要在 xtx-bread 组件插槽写注释,也会被解析。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值