Vue3 通过作用域插槽实现树形菜单嵌套组件

 更新时间:2023年01月19日 11:09:49   作者:SoaringHeart  
这篇文章主要为大家介绍了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

以上就是Vue3 通过作用域插槽实现树形菜单/嵌套组件的详细内容,更多关于Vue3 树形菜单嵌套组件的资料请关注脚本之家其它相关文章!

相关文章

  • 关于vuex更新视图引发的一些思考详析

    关于vuex更新视图引发的一些思考详析

    我们在vuex中操作数据时遇见视图不更新的情况,下面这篇文章主要给大家介绍了关于vuex更新视图引发的一些思考,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • vue3+vite+axios 配置连接后端调用接口的实现方法

    vue3+vite+axios 配置连接后端调用接口的实现方法

    这篇文章主要介绍了vue3+vite+axios 配置连接后端调用接口的实现方法,在vite.config.ts文件中添加配置,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • Vue实现图书管理小案例

    Vue实现图书管理小案例

    这篇文章主要为大家详细介绍了Vue实现图书管理小案例,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • Vue+TailWindcss实现一个简单的闯关小游戏

    Vue+TailWindcss实现一个简单的闯关小游戏

    本文将利用Vue+TailWindcss实现一个简单的闯关小游戏,玩家须躲避敌人与陷阱到达终点且拥有多个关卡,感兴趣的小伙伴可以了解一下
    2022-04-04
  • vue router demo详解

    vue router demo详解

    这篇文章主要为大家详细介绍了vue router demo演示代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • Vue动态改变css样式的3种方法总结

    Vue动态改变css样式的3种方法总结

    这篇文章主要给大家介绍了关于Vue动态改变css样式的3种方法,在Vue.js中我们经常需要根据特定的条件或事件来动态地修改CSS样式,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • 使用Webpack 搭建 Vue3 开发环境过程详解

    使用Webpack 搭建 Vue3 开发环境过程详解

    这篇文章主要介绍了使用Webpack 搭建 Vue3 开发环境过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 解决vue admin element noCache设置无效的问题

    解决vue admin element noCache设置无效的问题

    今天小编就为大家分享一篇解决vue admin element noCache设置无效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Vue中.env、.env.development及.env.production文件说明

    Vue中.env、.env.development及.env.production文件说明

    这篇文章主要给大家介绍了关于Vue中.env、.env.development及.env.production文件说明的相关资料,文中通过实例代码介绍的非常详细,对大家学习或者使用vue具有一定的参考学习价值,需要的朋友可以参考下
    2022-09-09
  • vue实现移动端返回顶部

    vue实现移动端返回顶部

    这篇文章主要为大家详细介绍了vue实现移动端返回顶部,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10

最新评论