手机版 欢迎访问it开发者社区(www.mfbz.cn)网站

当前位置: > 开发

vue3面包屑组件

时间:2021/9/18 22:48:41|来源:|点击: 次

顶级类目-面包屑组件

  • 终极版,使用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;
  &-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函数提供render(h){}函数用来创建节点
      • vue3.0 函数由 vue 直接提供,需要按需导入 import { h } from 'vue'
    • this.$slots.default() 获取默认插槽的节点结构,按照要求拼接结构。
    • h函数的传参 tag 标签名|组件名称, props 标签属性|组件属性, node 子节点|多个节点
    • 具体参考 render
  • 注意:不要在 xtx-bread 组件插槽写注释,也会被解析(用户不爽),改善用户体验

  • 基于jsx方式实现
<script>
// import { h } from 'vue'
export default {
  name: 'XtxBread',
  render () {
    // vue2的render函数的形参是 h 函数
    // vue3中h函数是导入的
    // createElement(标签名称, 标签的属性, 标签的子元素)
    // console.dir(this.$slots.default())
    // 获取XtxBread组件的所有的插槽里面填充组件实例
    const items = this.$slots.default()
    const results = []
    items.forEach((item, index) => {
      results.push(item)
      // 手动生成一个i图标,添加到面包屑项目的后面
      // const iTag = h('i', { class: 'iconfont icon-angle-right' })
      if (index < items.length - 1) {
        // results.push(iTag)
        results.push(<i className='iconfont icon-angle-right'></i>)
      }
    })
    // div的子节点应该动态生成:更加插槽的内容动态生成
    // return h('div', { class: 'xtx-bread' }, results)
    return <div className='xtx-bread'>{results}</div>
  }
}
</script>

总结:

  1. jsx其实就是直接在js代码中写HTML标签
  2. 标签中插入的动态值使用单个花括号(插值表达式)
  3. class名称需要换成className

Copyright © 2002-2019 某某自媒体运营 版权所有