zoukankan      html  css  js  c++  java
  • 如何用vue实现树形菜单?

           在公司培训了2周,布置的作业是从树形,grid分页以及echarts中选一个。由于都不是很熟,就挑了第一个。本来想在网上找找参考,然后模仿着做一个,但是网上的代码多少参差不齐,写到一半没了,所以只要自己写篇博客,记录下实现过程。

    一、准备工作:

    1.此次树形是用vue实现的,电脑需提前配置好node.js和vue.js,具体怎么配置,这里不作说明。

          1)如果不记得自己有没有安装,可以win+R调出运行窗口,输入cmd,按enter

       

        2)输入node -v和vue -V(注意vue中的-V是大写的)

    node -v

    vue -V

        

         如果显示了版本号,则意为已安装。

     2.引用奥森图标,进入官网下载包

       

    3.需要对vue和webpack有基本的了解

      一切准备就绪后,那么我们就开始吧

    二、安装

    1.首先在本地创建一个文件夹,命名为vue-tree,进入命令行窗口,然后进入到vue-tree文件夹所在位置

    2.安装vue-cli,用cnpm更快

     npm i -g vue-cli

         

         

    然后创建一个webpack项目并且下载依赖

    vue init webpack vue-tutorial

      

    进入到vue-tutorial文件夹里,cd vue-tutorial

    npm i

    然后

    npm run dev

    这时我们就可以在localhost:8080中查看我们的应用了。

     三、代码展示

    下面进入重点啦~

    1.打开你的main.js文件

    然后在src/components文件夹下新建2个vue文件,同时新建一个common文件夹,在里面新增一个vue文件,具体看图(这里的font-aswesome是我下载的一个压缩包),layout负责布局展示,index负责树形展示,treeMenu负责渲染。

    我们先配置好main.js

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Layout from './components/layout.vue'
    import IndexPages from './common/index.vue'
    import myTree from './components/treeMenu.vue'
    Vue.use(VueRouter)
    let router = new VueRouter({
        mode: 'history',
        routes: [
            {
                path: '/',
                component: IndexPages
            }
        ]
    })
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      template: '<Layout/>',
      components: { Layout }
    })

     2.打开layout.vue文件,开始编写(这段样式用的慕课一位讲师的)。其他的组件将在<router-view></router-view>中被渲染出来。

    /**
     * 页面的入口,负责页面的布局
     */
    
    <template>
      <div>
        <div class="app-head">
          <div class="app-head-inner">
            <img src="../assets/logo.png">
             <div class="head-nav">
              <ul class="nav-list">
                <li>登录</li>
                <li class="nav-pile">|</li>
                <li>注册</li>
                <li class="nav-pile">|</li>
                <li>关于</li>
              </ul>
            </div>
          </div>
        </div>
    
        <div class="container">
          <router-view></router-view>
        </div>
    
        <div class="app-foot">
          <p>© 2017 cindy</p>
        </div>
      </div>
    </template>
    
    <script>
    
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
    html, body, div, span, applet, object, iframe,
    h1, h2, h3, h4, h5, h6, p, blockquote, pre,
    a, abbr, acronym, address, big, cite, code,
    del, dfn, em, img, ins, kbd, q, s, samp,
    small, strike, strong, sub, sup, tt, var,
    b, u, i, center,
    dl, dt, dd, ol, ul, li,
    fieldset, form, label, legend,
    table, caption, tbody, tfoot, thead, tr, th, td,
    article, aside, canvas, details, embed, 
    figure, figcaption, footer, header, hgroup, 
    menu, nav, output, ruby, section, summary,
    time, mark, audio, video {
      margin: 0;
      padding: 0;
      border: 0;
      font-size: 100%;
      font: inherit;
      vertical-align: baseline;
    }
    /* HTML5 display-role reset for older browsers */
    article, aside, details, figcaption, figure, 
    footer, header, hgroup, menu, nav, section {
      display: block;
    }
    body {
      line-height: 1;
    }
    ol, ul {
      list-style: none;
    }
    
    a {
      color: inherit;
      text-decoration: none;
    }
    body {
      background: #f0f2f5;
      font-family: "Helvetica Neue",Helvetica,Arial,"Hiragino Sans GB","Hiragino Sans GB W3","Microsoft YaHei UI","Microsoft YaHei","WenQuanYi Micro Hei",sans-serif;
      font-size: 14px;
      color: #444;
    }
    .app-head {
      background: #363636;
      color: #b2b2b2;
      height: 90px;
      line-height: 90px;
      width: 100%;
    }
    .app-head-inner {
      width: 1200px;
      margin: 0 auto;
    }
    .app-head-inner img {
      width: 50px;
      margin-top: 20px;
    }
    .head-nav {
      float: right;
    }
    .head-nav ul {
      overflow: hidden;
    }
    .head-nav li {
      cursor: pointer;
      float: left;
    }
    .nav-pile {
      padding: 0 10px;
    }
    .app-foot {
      text-align: center;
      height: 80px;
      width: 100%;
      line-height: 80px;
      background: #e3e4e8;
      clear: both;
      margin-top: 30px;
    }
    .container {
      width: 1200px;
      height: 470px;
      margin: 0 auto;
    }
    ul li {
      padding-left: 10px;
    }
    
    </style>

     3.打开index.vue文件,代码如下,树形主要在<ul v-for="menuItem in theModel"> <myTree class="item" :model="menuItem"></myTree> </ul>实现。

    /**
     * 树形和echarts的展示
     */
    <template>
      <div class="index-wrap">
        <div class="index-left">
          <div class="index-left-block">
            <h2>树形侧边导航栏</h2>
            <ul v-for="menuItem in theModel">
              <myTree class="item" :model="menuItem"></myTree>
            </ul>
          </div>
        </div>
        <div class="index-right">
          <div class="index-right-block">
          </div>
        </div>
      </div>
    </template>
    
    <script>
    import myTree from '../components/treeMenu.vue'var myData =[{
      'id': '1',
      'menuName': 'echarts',
      'menuCode': '10',
      'children': [
      {
        'menuName': '地图',
        'menuCode': '11',
      },
      {
        'menuName': '柱状图',
        'menuCode': '12',
        'children': [
        {
          'menuName': '交错正负轴标签',
          'menuCode': '121'
        },
        {
          'menuName': '柱状图框选 ',
          'menuCode': '122'
        },
        {
          'menuName': '堆叠柱状图',
          'menuCode': '124'
        }]
      },
      {
        'menuName': '条形图',
        'menuCode': '13'
      }]
    },
    {
      'id': '2',
      'menuName': '树形结构',
      'menuCode': '21'
    },
    {
      'id': '3',
      'menuName': 'gird分页',
      'menuCode': '30'
                }]
    
    export default {
      name: 'items',
      props: ['model'],
      components: {
        myTree
      },
      data () {
        return {
          theModel: myData
        }
      }
    }
    </script>
    
    <style scoped>
    .index-wrap {
      width: 1200px;
      margin: 0 auto;
      overflow: hidden;
    }
    .index-left {
      float: left;
      width: 300px;
      text-align: left;
    }
    .index-right {
      float: left;
      width: 900px;
    }
    .index-left-block, .index-right-block{
      height: 450px;
      margin: 15px;
      background: #fff;
      box-shadow: 0 0 1px #ddd;
    }
    
    .index-left-block h2,.index-right-block h2 {
      background: #4fc08d;
      color: #fff;
      padding: 20px 20px;
      font-size: 1.5em;
    }
    
    .item {
      cursor: pointer;
    }
    ul{
      line-height: 40px;
      list-style-type: dot;
    }
    
    li div:active,li div:hover {
      background: #9FDABE;
      color: #eee;
    }
    
    ul li:hover {
      background: #A6C2B0;
    }
    
    </style>

    4.最重要的一个文件:treeMenu.vue。这个文件里有用到font-awesome,需要大家自行去官网下载。然后将压缩包解压后,放到src的下面。我将文件夹重名为“font-awesome”,然后在<script></script>标签里引用import '../font-awesome/css/font-awesome.min.css'

    /**
     * 树的组件,主要功能在这里实现
     * 
     */
    <template>
      
      <li>
        <div @click="toggle" @dblclick="changeType">
          <!-- isFolder判断是否存在子级改变图标 -->
          <i v-if="isFolder"uk-animation-="" class="fa " :class="[open?'fa-folder-open':'fa-folder']"></i>
         
          <i v-if="!isFolder" class="fa fa-file-image-o"></i>
          {{ model.menuName }}
          <i v-if="isFolder" class="fa " :class="[open ? 'fa-chevron-down' : 'fa-chevron-right']" style="display: inline-block;float: right;padding:13px 20px 0 0;"></i>
         
          
        </div>
    
        <ul v-show="open" v-if="isFolder">
          <tree-menu v-for="item in model.children" :model="item"></tree-menu>
          <li class="add" @click="addChild">
            <i class="fa fa-plus-square-o" style="padding-left: 20px;">
              <i style="display: inline-block;padding-left: 20px;">add</i>
            </i>
          </li>
        </ul>
      </li>
    </template>
    
    <script>
    import '../font-awesome/css/font-awesome.min.css'
    import Vue from 'vue'
    export default {
      name: 'treeMenu',
      props: ['model'],
      data() {
        return {
          open: false,
        }
      },
      computed: {
       isFolder:function() {
         return this.model.children && this.model.children.length
       }
      },
      methods: {
      toggle: function() {
          if(this.isFolder) {
            this.open = !this.open
          }
       },
        changeType: function() {
          if(!this.isFolder) {
            Vue.set(this.model,'children',[])
            this.addChild()
            this.open = true
          }
        },
        addChild: function() {
          this.model.children.push({
            name:'new stuff'
          })
        }
      }
    }
    </script>
    
    <style scoped>
    
    ul {
      line-height: 40px;
      list-style-type: dot;
    }
    li div:active,li div:hover {
      background: #9FDABE;
      color: #eee;
    }
    
    ul li:hover {
      background: #A6C2B0;
    }
    
    
    .fa-folder-open, .fa-folder, .fa-file-image-o {
    
      padding:0 20px;
    }
    
    
    
    </style>

    所以处理完之后,就是这样子的啦(echarts是后面加上去的,可以不用管)

    我把代码放到github上了,大家可以下载看看(github上的代码包含了echarts,大家注意搭配我的博客看)

    https://github.com/yuegreen/vueTree

    官网中也有关于树组件的实现,大家可以去参考参考

    https://cn.vuejs.org/v2/examples/tree-view.html

    如果对本文章有什么问题和建议,欢迎在评论区讨论~

  • 相关阅读:
    原创: How to build a query based on Definition Updates installed
    About SCCM 2012 UDA(User Device Affinity)
    《失业的程序员》(二十):中国式的二把手
    《失业的程序员》(十九):工作与感情之间的传球 .
    《失业的程序员》(十八):意外的项目之旅 .
    《失业的程序员》(十七):保姆式的服务
    《失业的程序员》(十六):技术和商务的结合
    《失业的程序员》(十五):商业头脑
    《失业的程序员》(十四):兄和弟,矛和盾
    《失业的程序员》(十三):平衡
  • 原文地址:https://www.cnblogs.com/cindy79/p/7229196.html
Copyright © 2011-2022 走看看