好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

一、需求来 源

工作中需要一种树形菜单组件,经过两天的构思最终通过作用域 插槽 实现: 此组件将每个节点(插槽名为 node)暴露出来。

通过插槽的 attributes 向当前插槽节点传递子项 IT em(数据对象)和level(层深)参数,在保持组件内部极简的同时支持在数据模型中扩展性。基本达到比较好的封装颗粒度,大家可以在此基础上无限扩展封装具体的业务逻辑。

二、效果图

let list = reactive(
  [{ 
    n am e:'1 一级菜单',
    isE xp and: 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="slot PR ops">
      <div class="tree-node">
        {{prefix(slotProps.level)}}{{slotProps.item.name}}{{sufix(slotProps.item)}}
      </div>
    </template>
  </VTreeNode>
</template>
<script  SETUP >
import VTreeNode  From  '@/ component s/VTreeNode/VTreeNode.vue';
import { ref, reactive, watch, on mount ed, } f rom  '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 '__'.re PE at(count);
};
const sufix = (item) => {
  if (!Reflect.has(item, 'child')) {
    return '';
  }
  return ` (${item.child.length}子项)`;
};
</script>
<style scoped lang='scss'>
.tree-node{
  h ei ght: 45px;
  dis play : flex;
  justify -s elf:  center ;
  align -i tems: 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 =  define Props({
  list: {
    type: Array,
    default: () => [],
    validator: (val) => {
      return Array.isArray(val) &am p; & 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前端开发层次嵌套组件的通信详解

总结

以上是 为你收集整理的 Vue3 通过作用域插槽实现树形菜单嵌套组件 全部内容,希望文章能够帮你解决 Vue3 通过作用域插槽实现树形菜单嵌套组件 所遇到的问题。

如果觉得 网站内容还不错, 推荐好友。

查看更多关于Vue3 通过作用域插槽实现树形菜单嵌套组件的详细内容...

  阅读:35次