所有分类
  • 所有分类
  • 后端开发
Vue3每日一学:通过作用域插槽实现树形菜单嵌套组件

Vue3每日一学:通过作用域插槽实现树形菜单嵌套组件

运行环境:Windows
所需软件:Word
资源类型:简历
资源下载
仅限注册用户下载,请先
解压密码:www.icz.com 使用版权:资源收集于网络,版权归原创者所有

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>
        {{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>
.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>
资源下载
下载价格免费
解压密码:www.icz.com 使用版权:资源收集于网络,版权归原创者所有
运行环境:Windows
所需软件:Word
资源类型:简历
原文链接:https://www.icz.com/technicalinformation/web/vue3/2023/04/8460.html,转载请注明出处~~~
0

评论0

请先
注意:请收藏好网址www.icz.com,防止失联!站内免费资源持续上传中…!赞助我们
显示验证码
没有账号?注册  忘记密码?