<template> 
 | 
  <div class="vol-el-menu"> 
 | 
    <div class="menu-search" v-if="showSearch"> 
 | 
      <el-select placement="bottom" v-model="searchValue" clearable filterable remote reserve-keyword 
 | 
        :placeholder="'请输入关键字搜索...'" :remote-method="remoteMethod" @change="selectChange" :loading="loading"> 
 | 
        <template #prefix><i class="el-icon-search"></i></template> 
 | 
        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> 
 | 
      </el-select> 
 | 
    </div> 
 | 
    <el-menu close="vol-el-menu--vertical" :default-openeds="openedIds" :default-active="defaultActive" 
 | 
      :unique-opened="true" @select="select" :collapse="isCollapse" @open="handleOpen" @close="handleClose" 
 | 
      @contextmenu.prevent="bindRightClickMenu"> 
 | 
      <template v-for="item in convertTree(list)"> 
 | 
        <el-sub-menu :key="item.id" :index="'' + item.id" v-if="item.children.length && (!enable || item.enable == 1)"> 
 | 
          <template #title> 
 | 
            <i class="menu-icon" :class="item.icon"></i> 
 | 
            <span> {{ item.name}}</span> 
 | 
          </template> 
 | 
          <vol-element-menu-child :enable="enable" :list="item.children"></vol-element-menu-child> 
 | 
        </el-sub-menu> 
 | 
        <template v-else> 
 | 
          <el-menu-item class="menu-item-lv1" v-if="!enable || item.enable == 1" :key="item.id" :index="'' + item.id"> 
 | 
            <i :class="item.icon"></i> 
 | 
            <span> {{ item.name }}</span> 
 | 
          </el-menu-item> 
 | 
        </template> 
 | 
      </template> 
 | 
    </el-menu> 
 | 
  </div> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
import VolElementMenuChild from "./VolElementMenuChild"; 
 | 
import { useRouter } from "vue-router"; 
 | 
  
 | 
import { 
 | 
  defineComponent, 
 | 
  reactive, 
 | 
  watch, 
 | 
  ref, 
 | 
  toRef, 
 | 
  toRefs, 
 | 
  getCurrentInstance, 
 | 
  // onMounted, 
 | 
} from "vue"; 
 | 
export default defineComponent({ 
 | 
  components: { 
 | 
    "vol-element-menu-child": VolElementMenuChild, 
 | 
  }, 
 | 
  props: { 
 | 
    enable: { 
 | 
      type: Boolean, 
 | 
      default: false, //是否判断enable=1 
 | 
    }, 
 | 
    isCollapse: { 
 | 
      type: Boolean, 
 | 
      default: false, 
 | 
    }, 
 | 
    onSelect: { 
 | 
      type: Function, 
 | 
      default: (x) => { }, 
 | 
    }, 
 | 
    openSelect: { 
 | 
      //打开的时候是否触发选中事件 
 | 
      type: Boolean, 
 | 
      default: true, 
 | 
    }, 
 | 
    list: { 
 | 
      type: Array, 
 | 
      default: [], 
 | 
    }, 
 | 
    rootId: { 
 | 
      type: String, 
 | 
      default: "0", 
 | 
    }, 
 | 
    currentMenuId: { 
 | 
      type: Number, 
 | 
      default: 0, 
 | 
    }, 
 | 
  }, 
 | 
  setup(props) { 
 | 
    // const { list } = toRefs(props); 
 | 
    //  const treeList = ref([]); 
 | 
    const getTree = (id, node, data) => { 
 | 
      if (!node.children) { 
 | 
        node.children = []; 
 | 
      } 
 | 
      data.forEach((x) => { 
 | 
        if (x.parentId == id && !node.children.some((c) => c.id === x.id)) { 
 | 
          node.children.push(x); 
 | 
          getTree(x.id, x, data); 
 | 
        } 
 | 
      }); 
 | 
    }; 
 | 
    let rootTreeId = !isNaN(props.rootId) ? ~~props.rootId : props.rootId; 
 | 
    props.list.forEach((x) => { 
 | 
      if (!x.icon || x.icon.substring(0, 3) != "el-") { 
 | 
        x.icon = "el-icon-menu"; 
 | 
      } 
 | 
      x.children = []; 
 | 
      x.isRoot = x.parentId === rootTreeId; 
 | 
    }); 
 | 
    const convertTree = (data) => { 
 | 
      var root_data = []; 
 | 
      data.forEach((x) => { 
 | 
        if (x.parentId === rootTreeId) { 
 | 
          if (!x.hasOwnProperty("enable")) x.enable = 1; 
 | 
          root_data.push(x); 
 | 
          getTree(x.id, x, data); 
 | 
        } 
 | 
      }); 
 | 
      return root_data; 
 | 
    }; 
 | 
    const openedIds = reactive([props.currentMenuId]); 
 | 
    const defaultActive = ref(props.currentMenuId + ""); 
 | 
    let _base = getCurrentInstance().appContext.config.globalProperties.base; 
 | 
    watch( 
 | 
      () => props.currentMenuId, 
 | 
      (newVal, oldVal) => { 
 | 
        defaultActive.value = newVal + ""; 
 | 
        openedIds.splice(0); 
 | 
        openedIds.push( 
 | 
          ..._base.getTreeAllParent(newVal, props.list).map((c) => { 
 | 
            return c.id; 
 | 
          }) 
 | 
        ); 
 | 
      } 
 | 
    ); 
 | 
    const router = useRouter(); 
 | 
    let eventSelect = false; 
 | 
    const select = (index, _item) => { 
 | 
  
 | 
      _item = props.list.find((x) => { 
 | 
        return x.id == index; 
 | 
      }); 
 | 
  
 | 
      if (_item.linkType == 1) { 
 | 
        window.open(_item.url || _item.path, '_blank') 
 | 
        return; 
 | 
      } 
 | 
      if (eventSelect) { 
 | 
        return; 
 | 
      } 
 | 
      eventSelect = true; 
 | 
      setTimeout(() => { 
 | 
        eventSelect = false; 
 | 
      }, 20); 
 | 
  
 | 
  
 | 
  
 | 
      props.onSelect(index, _item); 
 | 
      router.push({ path: _item.path || "", query: _item.query }); 
 | 
    }; 
 | 
  
 | 
    const handleOpen = (index, path) => { 
 | 
      if (props.openSelect) { 
 | 
        select(index, path); 
 | 
      } 
 | 
    }; 
 | 
    const handleClose = () => { }; 
 | 
  
 | 
    /** 
 | 
     * 菜单导航右键事件 
 | 
     * @param {*} enable 是否启用右键事件[true:启用;false:禁用;] 
 | 
     */ 
 | 
    const bindRightClickMenu = (enable) => { 
 | 
      if (!enable) return; 
 | 
    }; 
 | 
    const { proxy } = getCurrentInstance(); 
 | 
    const loading = ref(false) 
 | 
    const searchValue = ref(''); 
 | 
    const options = ref([]); 
 | 
    const remoteMethod = (query) => { 
 | 
      if (!query) { 
 | 
        options.value.length = 0; 
 | 
        return; 
 | 
      } 
 | 
      options.value = props.list 
 | 
        .filter(c => { return (c.enable == 1 || c.enable === undefined) && c.name.indexOf(query) != -1 && (!c.children || !c.children.length) }) 
 | 
        .map(x => { return { value: x.id, label: x.name } }).slice(0, 7) 
 | 
    } 
 | 
    const selectChange = (id) => { 
 | 
      if (!id) { 
 | 
        return; 
 | 
      } 
 | 
      let index = props.list.findIndex(c => { return c.id === id }); 
 | 
      if (index === -1) { 
 | 
        return; 
 | 
      } 
 | 
      searchValue.value = ""; 
 | 
      if(proxy.list.some(c=>{return c.parentId===id})){ 
 | 
        return; 
 | 
      } 
 | 
      select(id, props.list[index]); 
 | 
    } 
 | 
  
 | 
    const showSearch=ref(proxy.$global.menuSearch===undefined||proxy.$global.menuSearch) 
 | 
    return { 
 | 
      // treeList, 
 | 
      // list, 
 | 
      select, 
 | 
      convertTree, 
 | 
      handleOpen, 
 | 
      handleClose, 
 | 
      bindRightClickMenu, 
 | 
      openedIds, 
 | 
      defaultActive, 
 | 
      searchValue, 
 | 
      options, 
 | 
      remoteMethod, 
 | 
      loading, 
 | 
      selectChange, 
 | 
      showSearch 
 | 
    }; 
 | 
  }, 
 | 
}); 
 | 
</script> 
 | 
<style lang="less" scoped> 
 | 
.vol-el-menu { 
 | 
  // box-sizing: content-box; 
 | 
  width: 100%; 
 | 
  
 | 
  .menu-icon { 
 | 
    font-size: 18px; 
 | 
    margin-right: 6px; 
 | 
  } 
 | 
} 
 | 
  
 | 
.menu-search { 
 | 
  padding: 6px 10px; 
 | 
  
 | 
  ::v-deep(.el-input__wrapper) { 
 | 
    border-radius: 15px !important; 
 | 
  } 
 | 
} 
 | 
</style> 
 |