• Vue 自定义级联菜单


    Menu组件

      1 <template>
      2   <div class="menu" v-if="global.v > 0">
      3     <div>v:{{ global.v }} level:{{ global.level }}</div>
      4     <ul @mouseenter="enter()" @mouseleave="leave()">
      5       <li v-for="menu in menus" :key="menu.id" @mouseenter="active(menu)" :class="{ active: level <= global.level && activeMenuId == menu.id }">{{ menu.id }}_L{{ level }}</li>
      6     </ul>
      7     <div v-if="submenu && this.level - this.global.level < 1" class="menu-sub">
      8       <A :global="global" :level="level + 1" :menus="submenu"></A>
      9     </div>
     10   </div>
     11 </template>
     12 
     13 <script>
     14 export default {
     15   name: 'A',
     16   props: {
     17     global: {
     18       type: Object,
     19       default: () => {
     20         return { v: 0, level: 1 }
     21       }
     22     },
     23     level: {},
     24     menus: {}
     25   },
     26   components: {},
     27   data() {
     28     return {
     29       submenu: null,
     30       activeMenuId: null
     31     }
     32   },
     33   created() {},
     34   methods: {
     35     active(menu) {
     36       this.activeMenuId = menu.id
     37       this.delay(() => {
     38         this.submenu = menu.submenu
     39         console.info('show_sub_menu')
     40       })
     41     },
     42     enter() {
     43       this.global.level = this.level
     44     },
     45     leave() {
     46       this.delay(() => {
     47         if (this.level == this.global.level) this.global.level--
     48       })
     49     },
     50     showSub() {
     51       return this.submenu && this.level - this.global.level > 0
     52     },
     53     delay(cb, delay) {
     54       let v = ++this.global.v
     55       setTimeout(() => {
     56         if (this.global.v === v) {
     57           cb()
     58         }
     59       }, delay || 50)
     60     },
     61     hide() {
     62       this.global.v = 0
     63     },
     64     show() {
     65       this.global.v = 1
     66     }
     67   }
     68 }
     69 </script>
     70 
     71 <style>
     72 .menu {
     73   display: inline-block;
     74   position: relative;
     75   border: solid 1px #abc;
     76   padding: 0px;
     77   min-width: 100px;
     78   background-color: beige;
     79 }
     80 
     81 .menu ul {
     82   padding: 0;
     83   margin: 0;
     84 }
     85 
     86 .menu .menu-sub {
     87   position: absolute;
     88   top: 0;
     89   left: 100%;
     90 }
     91 
     92 .menu ul li {
     93   list-style: none;
     94   margin: 2px;
     95   padding: 2px 10px;
     96 }
     97 
     98 .menu .active {
     99   background-color: rgb(183, 218, 250);
    100 }
    101 </style>

    使用

     1 <template>
     2   <div class="hello">
     3     <div><button @click="showMenu">File</button></div>
     4     <A :level="1" :menus="menus" ref="GMenu"></A>
     5   </div>
     6 </template>
     7 
     8 <script>
     9 import A from './A'
    10 
    11 let menus = [
    12   {
    13     id: 'a',
    14     submenu: [
    15       {
    16         id: 'aa',
    17         submenu: [{ id: 'aaa' }, { id: 'aab' }, { id: 'aac' }]
    18       },
    19       { id: 'ab' },
    20       { id: 'ac' }
    21     ]
    22   }
    23 ]
    24 
    25 let makeMenu = (menus, pid, deep) => {
    26   let m = Math.floor(Math.random() * 10) + 9
    27   for (let index = 0; index < m; index++) {
    28     let menu = { id: pid + '' + index }
    29     let submenu = []
    30     if (deep < 3) {
    31       menu.submenu = makeMenu(submenu, menu.id, deep + 1)
    32     }
    33     menus.push(menu)
    34   }
    35   return menus
    36 }
    37 
    38 makeMenu(menus, 'm', 1)
    39 
    40 console.info(menus)
    41 
    42 export default {
    43   components: { A },
    44   name: 'HelloWorld',
    45   data() {
    46     return {
    47       menus: menus
    48     }
    49   },
    50   props: {
    51     msg: String
    52   },
    53   created() {
    54     let self = this
    55     document.getElementsByTagName('body')[0].addEventListener('click', (e) => {
    56       e.stopPropagation()
    57       e.preventDefault()
    58       if (e.target.tagName === 'BODY') {
    59         console.log(e)
    60         self.hideMenu()
    61       }
    62     })
    63   },
    64   methods: {
    65     showMenu() {
    66       this.$refs.GMenu.show()
    67     },
    68     hideMenu() {
    69       this.$refs.GMenu.hide()
    70     }
    71   }
    72 }
    73 </script>
    74 
    75 <!-- Add "scoped" attribute to limit CSS to this component only -->
    76 <style scoped>
    77 h3 {
    78   margin: 40px 0 0;
    79 }
    80 ul {
    81   list-style-type: none;
    82   padding: 0;
    83 }
    84 li {
    85   display: inline-block;
    86   margin: 0 10px;
    87 }
    88 a {
    89   color: #42b983;
    90 }
    91 </style>
  • 相关阅读:
    前后端分离的坑
    appscan 对于csrf漏洞扫描的坑
    appscan执行过程
    app scan状态码的坑
    linux修改jdk版本
    软件测试之性能测试
    jmeter 从文件中读取内容 CSV数据文件设置(CSV Data Set Config)
    robotframework基本操作
    robotframework生成随机数
    RobotFramework获取table的行数
  • 原文地址:https://www.cnblogs.com/sanshizi/p/14978741.html
Copyright © 2020-2023  润新知