通过render渲染,h函数封装面包屑组件
单纯的用组件封装,Vue注册, 组件引用,对于面包屑这一类层叠性较高的组件并不灵活:未来可能有更多级层的类目,顶级面包屑内容不好修改等
需要面包屑的组件:
<Bread parentPath="/category/1005000" parentName="电器">空调</Bread>
通过 render 渲染,h 函数封装面包屑功能(渲染虚拟DOM)
虚拟DOM:https://blog.csdn.net/qq_42778001/article/details/95959531
//HTML结构 <div id="app"> <p className="text">11</p> </div> //转虚拟DOM: { tag:"div", props:{ id:"app" }, children:[ { tag:"p", props:{ className:"text" }, children:[ 11 ] } ] }
h函数:就是vue中的createElement方法,函数作用就是创建虚拟dom,追踪dom变化
createElement:createElment函数接受三个参数,分别是:
- 参数一:tag(标签名)、组件的选项对象、函数(必选);
- 参数二:一个对象,标签的属性对应的数据(可选);
- 参数三:子级虚拟节点,字符串形式或数组形式,子级虚拟节点也需要使用createElement构建。
指定组件显示的内容:new Vue({选项})
- el 选项,通过一个选择器找到容器,容器内容就是组件内容
- template 选项,
<div>组件内容</div>
作为组件内容 - render选项:(createElement: () => VNode) => VNode。它是一个函数,函数会默认传入createElement的函数(h),这个函数用来创建结构,render再返回该结构渲染为组件内容。它的优先级更高。
<!--若要使用render,把template去掉--> <!--<template>--> <!--</template>-->
script部分:
import { h } from "vue"; render() { //vue2.0 的h函数传参进来的,vue3.0 的h函数导入进来 // 1. 创建bread父容器 // 2. 获取子节点数组,默认插槽内容 const items = this.$slots.default(); // 3. 去除bread-item组件的i标签,因该由render函数来组织 // 4. 遍历插槽中的item,得到一个动态创建的节点,最后一个item不加i标签 const dymanicItems = []; items.forEach((item, i) => { dymanicItems.push(item); //最后一个不添加i标签 if (i < items.length - 1) { dymanicItems.push(h("i", { class: "iconfont icon-angle-right" })); } }); // 5. 把动态创建的节点渲染再bread标签中 //h 第一个参数 标签名字 第二个参数 标签属性对象 第三个参数 子节点 return h("div", { class: "xtx-bread" }, dymanicItems); },
面包屑总结(可扩展至其他自定义render):render 是vue提供的一个渲染函数,优先级大于el,template等选项,用来提供组件结构:
三个文件:index首页 / bread面包屑整体结构 / bread-item面包屑
- 先将bread组件的template标签去除,保证render的优先性
- 用this.$slots.default() 获取首页调用bread组件时的子节点数组,插槽插入的node结构:三级面包屑或更多(可存入数组)
- 遍历数组,按照要求拼接结构,可在结构内再调用h函数创建新标签(h 第一个参数 标签名字 第二个参数 标签属性对象 第三个参数 子节点)
- 返回面包屑整体结构
- 注意:
- vue2.0 render函数提供h(createElement)函数用来创建节点
- vue3.0 h(createElement)函数有 vue 直接提供,需要按需导入