首页前端开发VUEVue3 通过作用域插槽实现树形菜单嵌套组件

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

时间2024-02-11 05:16:03发布访客分类VUE浏览568
导读:收集整理的这篇文章主要介绍了Vue3 通过作用域插槽实现树形菜单嵌套组件,觉得挺不错的,现在分享给大家,也给大家做个参考。 目录一、需求来源二、效果图三、使用示例(VTreeNodeDe...
收集整理的这篇文章主要介绍了Vue3 通过作用域插槽实现树形菜单嵌套组件,觉得挺不错的,现在分享给大家,也给大家做个参考。
目录
  • 一、需求来源
  • 二、效果图
  • 三、使用示例(VTreeNodeDemo.vue)
  • 四、源码(VTreeNode.vue):

一、需求来源

工作中需要一种树形菜单组件,经过两天的构思最终通过作用域插槽实现: 此组件将每个节点(插槽名为 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 @R_406_2150@ '@/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 树形菜单嵌套组件的资料请关注其它相关文章!

您可能感兴趣的文章:
  • vue实现带复选框的树形菜单
  • Vue递归实现树形菜单方法实例
  • vue实现树形菜单效果
  • vue嵌套组件传参实例分享
  • vue使用refs获取嵌套组件中的值过程
  • vue前端开发层次嵌套组件的通信详解

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Vue3 通过作用域插槽实现树形菜单嵌套组件
本文地址: https://pptw.com/jishu/609367.html
vant3中使用List组件的一些坑 vue中van-picker的选项插槽的使用

游客 回复需填写必要信息