Vue3 通过作用域插槽实现树形菜单嵌套组件
作者:SoaringHeart 发布时间:2024-05-28 15:42:28
标签:Vue3,树形菜单,嵌套组件,作用域,插槽
一、需求来源
工作中需要一种树形菜单组件,经过两天的构思最终通过作用域插槽实现: 此组件将每个节点(插槽名为 node)暴露出来。
通过插槽的 attributes 向当前插槽节点传递子项 item(数据对象)和level(层深)参数,在保持组件内部极简的同时支持在数据模型中扩展性。基本达到比较好的封装颗粒度,大家可以在此基础上无限扩展封装具体的业务逻辑。
二、效果图
let list = reactive(
[{
name:'1 一级菜单',
isExpand: true,//是否展开子项
enabled: false,//是否可以响应事件
child:[
{ name:'1.1 二级菜单',
isExpand: true,
child:[
{ name:'1.1.1 * 菜单', isExpand: true, },
]
},
{ name:'1.2 二级菜单', isExpand: true, },
]
},
{
name:'1.1 一级菜单',
isExpand: true,
child:[
{ name:'1.1.1 二级菜单', isExpand: true, },
{ name:'1.1.2 二级菜单',
isExpand: false,
child:[
{ name:'1.1.2.1 * 菜单', isExpand: true, },
]},
]
},]
);
三、使用示例(VTreeNodeDemo.vue)
<template>
<VTreeNode
:list="list"
:level="level"
>
<template #node="slotProps">
<div class="tree-node">
{{prefix(slotProps.level)}}{{slotProps.item.name}}{{sufix(slotProps.item)}}
</div>
</template>
</VTreeNode>
</template>
<script setup>
import VTreeNode from '@/components/VTreeNode/VTreeNode.vue';
import { ref, reactive, watch, onMounted, } from 'vue';
let list = reactive(
[{
name:'1 一级菜单',
isExpand: true,//是否展开子项
enabled: false,//是否可以响应事件
child:[
{ name:'1.1 二级菜单',
isExpand: true,
child:[
{ name:'1.1.1 * 菜单', isExpand: true, },
]
},
{ name:'1.2 二级菜单', isExpand: true, },
]
},
{
name:'1.1 一级菜单',
isExpand: true,
child:[
{ name:'1.1.1 二级菜单', isExpand: true, },
{ name:'1.1.2 二级菜单',
isExpand: false,
child:[
{ name:'1.1.2.1 * 菜单', isExpand: true, },
]},
]
},]
);
const level = ref(0);
const prefix = (count) => {
return '__'.repeat(count);
};
const sufix = (item) => {
if (!Reflect.has(item, 'child')) {
return '';
}
return ` (${item.child.length}子项)`;
};
</script>
<style scoped lang='scss'>
.tree-node{
height: 45px;
display: flex;
justify-self: center;
align-items: center;
// background-color: green;
border-bottom: 1px solid #e4e4e4;
}
</style>
四、源码(VTreeNode.vue):
<template>
<!-- <div> -->
<div v-for="(item,index) in list" :key="index">
<slot name="node" :item="item" :level="levelRef">
<div>{{ item.name }}</div>
</slot>
<div v-show="item.child && canExpand(item)" >
<VTreeNode :list="item.child" :level="levelRef">
<template #node="slotProps">
<slot name="node" :item="slotProps.item" :level="slotProps.level">
<div>{{ slotProps.item.name }}</div>
</slot>
</template>
</VTreeNode>
</div>
</div>
<!-- </div> -->
</template>
<script setup>
import { ref, reactive, watch, computed, onMounted, } from 'vue';
const props = defineProps({
list: {
type: Array,
default: () => [],
validator: (val) => {
return Array.isArray(val) && val.every(e => Reflect.has(e, 'name'));
}
},
level: {
type: Number,
default: 0,
}
});
const emit = defineEmits(['update:level', ])
const levelRef = computed({
set: (newVal) => {
if (props.level !== newVal) {
emit("update:level", newVal);
}
},
get: () => {
const tmp = props.level + 1;
return tmp;
},
});
const canExpand = (item) => {
return Reflect.has(item, 'isExpand') && item.isExpand;
};
// onMounted(() => {
// console.log(`levelRef:${levelRef.value}`);
// });
</script>
VTreeNode.vue
VTreeNodeDemo.vue
来源:https://juejin.cn/post/7165359183582199815


猜你喜欢
- 阅读上一篇:FrontPage XP设计教程5——表单的设计 在制作出图文并茂的网页之后,很多读者朋友还想让自己的网页能够播放音乐、视频等多
- 前言ECharts是由百度开源的基于JS的商业级数据图表库,有很多现成的图表类型和实例,而Pyecharts则是为了方便我们使用Python
- innerHTML,outerHTML innerHTML检索或设置标签内的内容;outerHTML检索或设置整个标签的内容(包含标签)。&
- 使用vscode的过程中 自己或者push代码以后 代码的格式可能会出现错乱,作为一个成熟的开发 , 当然应该遵守一些代码规范, 首先代码整
- 第一招、mysql服务的启动和停止net stop mysqlnet start mysql第二招、登陆mysql语法如下: mysql -
- 反射是在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取的信息以及动态调用对象
- 1.前端接口调用2.register访问入口//查询一个用户下所有的subnetws.Route(ws.GET("/subnets
- Python3 基础语法编码默认情况下,Python 3 源码文件以 UTF-8 编码,所有字符串都是 unicode 字符串。当然你也可以
- 我们提倡尽可能使用CSS,而且我们常常能做到这一点。现代浏览器有很好的CSS支持-这无疑足够好让你使用CSS来控制布局和版面设计。但是有时候
- 使用Python获取网段的IP个数以及地址清单需要用到IPy的库,而相应的方法主要就是IP。写小脚本如下: from IPy import
- # -*- coding: utf-8 -*- import numpy as npimport matplotlib.pyplot as
- 身为一名小小的程序猿,在日常开发中不可以避免的要和where in和like打交道,在大多数情况下我们传的参数不多简单做下单引号、敏感字符转
- 堆 heap 值类型 原始类型(primitive type) Undefined: undefined (注意大小写:类型/ 值,下同)
- 例如torch.nn.ReLU(inplace=True)inplace=True表示进行原地操作,对上一层传递下来的tensor直接进行修
- 使用使用navicat连接远程linux mysql数据库出现10061未知故障,设置使用ssh连接后出现2013故障本机环境:win10
- 匹配括号接下来,我们使用栈解决实际的计算机科学问题。比如我们都写过这样所示的算术表达式, ( 5 + 6 ) ∗ (
- with 用法理解Overviewwith 与with之后的object一起,起到了抛出异常和单独生成一个空间让代码在空间里运行的效果。实验
- Mysql索引索引介绍索引是什么官方介绍索引是帮助MySQL高效获取数据的数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据
- 1、块级作用域想想此时运行下面的程序会有输出吗?执行会成功吗?#块级作用域if 1 == 1: name = "lzl"
- bug1无法正常使用cmd或pycharm正常安装,报错截图如下:解决(1): 这种情况下,我们就不能使用cmd或pycharm进