zoukankan      html  css  js  c++  java
  • Vue.js递归组件实现动态树形菜单

    使用Vue递归组件实现动态菜单

    • 现在很多项目的菜单都是动态生成的,之前自己做项目也是遇到这种需求,翻看了官网案例,和网上大神的案例.只有两个感觉,官网的案例太简洁,没有什么注释,看起来不太好理解,大神们的作品又比较复杂,对于初学者来说理解起来还是有难度,自己捣鼓了几天,勉强理解了递归组件菜单的实现,这里结合官网的案例,把代码和注释附上.

    • 如果你的项目是element-ui,其实它里面也有提供树形菜单,但是由于是别人封装的,所以使用起来没那么方便,大多数还是会自己配置,好了,不说那么多,还是回到递归组件上来吧

    • 先来看一下菜单的最终效果,有+号的都是可以点击展开的
    •             
    • 首先看一下项目的目录,在后台菜单数据没拿到之前,这里先演示一个模拟数据的,先在SRC文档下建一个data存放菜单数据.按照菜单层级关系写 数据里设置menuLevel是为了配置路由的,值是组件的名字

    • 接着创建两个组件,一个是菜单父组件,一个是递归的子组件,父组件代码:

    • <template>
          <div>
              <ul id="demo">
                  <submenu
                    class="item"
                    :model="treeData">
                  </submenu>
              </ul>
          </div>
      </template>
      <script>
          // 引入菜单数据
          import data from '../../data/treeData'
          // 引入子组件
          import submenu from './submenu/submenu.vue'
          export default {
              components: {
                  submenu
              },
              name: 'treeMenu',
              data () {
                  return {
                      treeData: data
                  }
              }
          }
      </script>
      <style scoped>
          @import './treeMenu.scss';
       </style>
    • 子组件代码,html部分:
    • <template>
        <div>
          <li>
            <div
              :class="{bold: isFolder}"
              @click="toggle"
              @dblclick="changeType">
              <!-- 配置路由跳转 -->
              <router-link :to="{ name: model.menuLevel }">{{ model.name }}</router-link>
              
              <span v-if="isFolder">[{{ open ? '-' : '+' }}]</span>
            </div>
            <ul v-show="open" v-if="isFolder">
              <submenu
                class="item"
                v-for="(model, index) in model.children"
                :key="index"
                :model="model">
                
              </submenu>
              <!-- <li class="add" @click="addChild">+</li> -->
            </ul>
          </li>
        </div>
      </template>

      子组件代码,js部分:

    • // 引入子组件
      import submenu from './submenu'
      export default {
          components: {
              submenu
          },
          name: 'submenu',
          props: {
              model: Object
          },
          data: function () {
              return {
              open: false
              }
          },
          computed: {
              // 是否展示+图标
              isFolder: function () {
              return this.model.children &&
                  this.model.children.length
              }
          },
          methods: {
              // 单击展示子菜单
              toggle: function () {
                  if (this.isFolder) {
                      this.open = !this.open
                  }
              },
              // 双击给当前单一不可展开的菜单添加children,变成可展开样式
              changeType: function () {
                  if (!this.isFolder) {
                      // Vue.set(this.model, 'children', [])
                      this.$set(this.model, 'children', [])
                      this.addChild()
                      this.open = true
                  }
              },
              // 给子菜单添加内容
              addChild: function () {
              this.model.children.push({
                  name: 'new stuff'
              })
              }
          }
      }

      路由配置,这里的name和data数据里的menuLevel一样:

    • import Vue from 'vue'
      import Router from 'vue-router'
      // import OnePage from '@/components/OnePage/OnePage'
      // 引入菜单组件
      import treeMenu from '@/components/menu/treeMenu'
      // 引入一级菜单
      import one from '@/components/one/one'
      // 引入二级菜单
      import two from '@/components/two/two'
      // 引入三级菜单
      import three from '@/components/three/three'
      
      Vue.use(Router)
      
      export default new Router({
        routes: [
          // {
          //   path: '/',
          //   name: 'OnePage',
          //   component: OnePage
          // }
          {
            path: '/',
            name: 'treeMenu',
            component: treeMenu
          },
          {
            path: '/one',
            name: 'one',
            component: one
          },
          {
            path: '/two',
            name: 'two',
            component: two
          },
          {
            path: '/three',
            name: 'three',
            component: three
          }
        ]
      })

      这样一个树形菜单就大致完成了,配置了路由的也可以跳转到相应页面,如果菜单数据是后台给你的,数据只要和你一开始设置data数据格式一样就可以直接用了

  • 相关阅读:
    小公司的技术分享怎么搞
    当他们说「独立思考」时,到底在说什么
    java使用tika批量识别文件的真实mime类型
    hibernate:Not all named parameters have been
    mybatis出错:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.xxx.yyy.dao.ProjectMapper.getById
    Mysql Hibernate报错
    tomcat中多个端口部署项目
    Windows Server 2012多个winlogon.exe LogonUI.exe dwm.exe ChsIME.exe进程
    springboot使用profile指定不同配置(尚硅谷)
    springboot配置文件占位符(尚硅谷)
  • 原文地址:https://www.cnblogs.com/steamed-twisted-roll/p/9178013.html
Copyright © 2011-2022 走看看