Vue + Vue-router + Element-ui 搭建一個很是簡單的dashboard demo

作完這個demo後,我體會到,Vue組件化,webpack, Vue-router等,並非很難學習, 你須要的只是拿起斧頭的勇氣

在作demo的過程當中,我遇到一個問題,就是vue-router懶加載一直實現不了,糾結了半天。後來回到原點,去vue-route官網看文檔,發現是由於syntax-dynamic-import插件沒有安裝css

因此說:你覺得的bug, 其實是你沒看透文檔html

初次學習這個教程,你不須要有任何擔心某些東西不會,你也不須要寫任何代碼。由於基本上全部代碼都是從element官網上拷貝的,你所作的只是把他們組裝在一塊兒罷了。vue

在線預覽
倉庫地址:https://github.com/wangduandu...webpack

效果圖:
圖片描述
使用到的技術:git

  • Vue
  • Vue-router
  • Element-ui
  • webpack
  • Normalize.css
  • vue-awesome
  • babel

1 vue-cli 安裝模板

➜  vue-el-dashboard git:(master) vue init webpack

? Generate project in current directory? Yes
? Project name vue-el-dashboard
? Project description A Vue.js project
? Author wangdd <wangdd@welljoint.com>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Setup unit tests No
? Setup e2e tests with Nightwatch? No

   vue-cli · Generated "vue-el-dashboard".

   To get started:

     npm install
     npm run dev

   Documentation can be found at https://vuejs-templates.github.io/webpack

2 安裝依賴並運行

➜  vue-el-dashboard git:(master) ✗ cnpm i
✔ Installed 44 packages
✔ Linked 680 latest versions
➜ npm run dev

瀏覽器打開以下頁面:github

圖片描述

3 安裝初始化頁面佈局

安裝並使用Element UIweb

cnpm i element-ui -S

修改 /src/main.js 爲:vue-router

import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

import App from './App'

Vue.config.productionTip = false

Vue.use(ElementUI)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})

我須要的佈局是這種:
圖片描述vue-cli

Element 上覆制對應的代碼,
並粘貼到 /src/App.vue文件中:npm

<template>
  <div id="app">

    <el-container>
      <el-header>Header</el-header>
      <el-container>
        <el-aside width="200px">Aside</el-aside>
        <el-main>Main</el-main>
      </el-container>
    </el-container>

  </div>
</template>

<script>

export default {
  name: 'app'
}

</script>

<style>

</style>

不出意外的話,你能夠在瀏覽器上看到以下佈局:
圖片描述

如今,佈局就這麼成了。

4 安裝側邊菜單欄

我須要側邊欄是下圖右邊的自定義顏色的那種菜單
圖片描述

在components文件夾下新建NavMenu.vue

<template>
  <el-row class="tac">
    <el-col :span="12">
      <h5>默認顏色</h5>
      <el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose">
        <el-submenu index="1">
          <template slot="title">
            <i class="el-icon-location"></i>
            <span>導航一</span>
          </template>
          <el-menu-item-group>
            <template slot="title">分組一</template>
            <el-menu-item index="1-1">選項1</el-menu-item>
            <el-menu-item index="1-2">選項2</el-menu-item>
          </el-menu-item-group>
          <el-menu-item-group title="分組2">
            <el-menu-item index="1-3">選項3</el-menu-item>
          </el-menu-item-group>
          <el-submenu index="1-4">
            <template slot="title">選項4</template>
            <el-menu-item index="1-4-1">選項1</el-menu-item>
          </el-submenu>
        </el-submenu>
        <el-menu-item index="2">
          <i class="el-icon-menu"></i>
          <span slot="title">導航二</span>
        </el-menu-item>
        <el-menu-item index="3">
          <i class="el-icon-setting"></i>
          <span slot="title">導航三</span>
        </el-menu-item>
      </el-menu>
    </el-col>
    <el-col :span="12">
      <h5>自定義顏色</h5>
      <el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
        <el-submenu index="1">
          <template slot="title">
            <i class="el-icon-location"></i>
            <span>導航一</span>
          </template>
          <el-menu-item-group>
            <template slot="title">分組一</template>
            <el-menu-item index="1-1">選項1</el-menu-item>
            <el-menu-item index="1-2">選項2</el-menu-item>
          </el-menu-item-group>
          <el-menu-item-group title="分組2">
            <el-menu-item index="1-3">選項3</el-menu-item>
          </el-menu-item-group>
          <el-submenu index="1-4">
            <template slot="title">選項4</template>
            <el-menu-item index="1-4-1">選項1</el-menu-item>
          </el-submenu>
        </el-submenu>
        <el-menu-item index="2">
          <i class="el-icon-menu"></i>
          <span slot="title">導航二</span>
        </el-menu-item>
        <el-menu-item index="3">
          <i class="el-icon-setting"></i>
          <span slot="title">導航三</span>
        </el-menu-item>
      </el-menu>
    </el-col>
  </el-row>
</template>

<script>
  export default {
    methods: {
      handleOpen(key, keyPath) {
        console.log(key, keyPath);
      },
      handleClose(key, keyPath) {
        console.log(key, keyPath);
      }
    }
  }
</script>

而後將NavMenu組件導入到App.vue中, 修改App.vue:

<template>
  <div id="app">

    <el-container>
      <el-header>Header</el-header>
      <el-container>
        <el-aside width="200px">
          <navmenu></navmenu>
        </el-aside>
        <el-main>Main</el-main>
      </el-container>
    </el-container>

  </div>
</template>

<script>
import NavMenu from '@/components/NavMenu'

export default {
  name: 'app',
  components: {
    'navmenu': NavMenu
  }
}

</script>

<style>

</style>

這裏要解釋一下這條語句, 該語句中的@, 符號是什麼意思?

import NavMenu from '@/components/NavMenu'

在build/webpack.base.conf.js中有以下代碼, alias就是起別名,@符號就是表明src路徑, 因此@/components/NavMenu就是src/components/NavMenu。 這樣webpack就知道如何引入文件了。這樣作的好處是沒必要處處去寫src了。

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },

如今打開瀏覽器,應該能夠看到以下界面:
圖片描述

能夠看到菜單已經引入進來了,可是是兩個菜單,下面咱們須要修改一下,只要右邊的菜單,並刪除一些多餘的元素。
修改NavMenu.vue文件。

<template>
  <el-row class="tac">
    <el-col :span="24">
      <el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
      unique-opened
      router
      background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
        <el-submenu index="1">
          <template slot="title">
            <i class="el-icon-location"></i>
            <span>導航一</span>
          </template>
          <el-menu-item-group>
            <el-menu-item index="1-1">選項1</el-menu-item>
            <el-menu-item index="1-2">選項2</el-menu-item>
            <el-menu-item index="1-3">選項3</el-menu-item>
            <el-menu-item index="1-4">選項4</el-menu-item>
          </el-menu-item-group>
        </el-submenu>

        <el-submenu index="2">
          <template slot="title">
            <i class="el-icon-location"></i>
            <span>導航二</span>
          </template>
          <el-menu-item-group>
            <el-menu-item index="2-1">選項1</el-menu-item>
            <el-menu-item index="2-2">選項2</el-menu-item>
            <el-menu-item index="2-3">選項3</el-menu-item>
            <el-menu-item index="2-4">選項4</el-menu-item>
          </el-menu-item-group>
        </el-submenu>

      </el-menu>
    </el-col>
  </el-row>
</template>

<script>
  export default {
    methods: {
      handleOpen(key, keyPath) {
        console.log(key, keyPath)
      },
      handleClose(key, keyPath) {
        console.log(key, keyPath)
      }
    }
  }
</script>

如今打開瀏覽器看看:
圖片描述

點擊展開菜單看看:
圖片描述

5 側邊菜單欄進階

咱們須要的功能:

  1. 每次只能展開一個一級菜單
  2. 每次點擊一個二級菜單能夠自動改變路由,跳轉到對應的組件
  3. 因爲菜單在路由中也會使用,因此最好抽象出來,作成一個配置文件

第1點和第二點比較好搞,Element上已經有配置文檔:

  • unique-opened: 是否只保持一個子菜單的展開
  • router: 是否使用 vue-router 的模式,啓用該模式會在激活導航時以 index 做爲 path 進行路由跳轉

圖片描述

修改NavMenu.vue

<template>
  <el-row class="tac">
    <el-col :span="24">
      <el-menu default-active="2" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
      unique-opened
      router
      background-color="#545c64" text-color="#fff" active-text-color="#ffd04b">
        <el-submenu index="1">
          <template slot="title">
            <i class="el-icon-location"></i>
            <span>導航一</span>
          </template>
          <el-menu-item-group>
            <el-menu-item index="1-1">選項1</el-menu-item>
            <el-menu-item index="1-2">選項2</el-menu-item>
            <el-menu-item index="1-3">選項3</el-menu-item>
            <el-menu-item index="1-4">選項4</el-menu-item>
          </el-menu-item-group>
        </el-submenu>

        <el-submenu index="2">
          <template slot="title">
            <i class="el-icon-location"></i>
            <span>導航二</span>
          </template>
          <el-menu-item-group>
            <el-menu-item index="2-1">選項1</el-menu-item>
            <el-menu-item index="2-2">選項2</el-menu-item>
            <el-menu-item index="2-3">選項3</el-menu-item>
            <el-menu-item index="2-4">選項4</el-menu-item>
          </el-menu-item-group>
        </el-submenu>

      </el-menu>
    </el-col>
  </el-row>
</template>

<script>
  export default {
    methods: {
      handleOpen (key, keyPath) {
        console.log(key, keyPath)
      },
      handleClose (key, keyPath) {
        console.log(key, keyPath)
      }
    }
  }
</script>

打開瀏覽器,點擊一個二級菜單看看,你會發現,效果並不像預期那樣,並且控制檯還向你扔出一個bug:
圖片描述

添加一個暫時的路由: 修改main.js

import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

import App from './App'
import router from './router'

Vue.config.productionTip = false

Vue.use(ElementUI)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

打開瀏覽器,點擊一個二級菜單,這時候沒有報錯,瀏覽器的路徑也變了, 變成http://localhost:8080/#/1-3
圖片描述

每次增長一個菜單都要寫點html是不能忍的,能用js的,就別用html

在src目錄下建立一個config目錄,目錄下建立一個menu-config.js 文件:
外層的數組表明一級菜單,內層sub數組表明二級菜單。

module.exports = [{
  name: '基礎',
  id: 'basic',
  sub: [{
    name: 'Layout 佈局',
    componentName: 'BasicLayout'
  }, {
    name: 'Container 佈局容器',
    componentName: 'BasicContainer'
  }]
}, {
  name: 'Form',
  id: 'form',
  sub: [{
    name: 'Radio 單選框',
    componentName: 'FormRadio'
  }, {
    name: 'Checkbox 多選框',
    componentName: 'FormCheckbox'
  }]
}]

在NavMenu.vue中引入這個文件,並使用v-for循環去渲染這個菜單:

<template>
  <el-row class="tac">
  <el-col :span="24">
    <el-menu
      class="el-menu-vertical-demo"
      router
      unique-opened
      @open="handleOpen"
      @close="handleClose"
      background-color="#545c64"
      text-color="#fff"
      active-text-color="#ffd04b">

      <el-submenu v-for="item in menu" :index="item.id" :key="item.id">
        <template slot="title">
          <span v-text="item.name"></span>
        </template>
        <el-menu-item-group class="over-hide" v-for="sub in item.sub" :key="sub.componentName">
          <el-menu-item :index="sub.componentName" v-text="sub.name">
          </el-menu-item>
        </el-menu-item-group>
      </el-submenu>

    </el-menu>
  </el-col>
</el-row>
</template>

<style scoped>
  .over-hide{
    overflow: hidden;
  }
</style>

<script>
  import menu from '@/config/menu-config'

  export default {
    data () {
      return {
        menu: menu
      }
    },
    methods: {
      handleOpen (key, keyPath) {
        console.log(key, keyPath)
      },
      handleClose (key, keyPath) {
        console.log(key, keyPath)
      }
    }
  }
</script>

這裏要說明一下,我給二級菜單加上了over-hide類,二級菜單在展開時,有點溢出父元素了。
打開瀏覽器看看, 這時候菜單已是根據配置文件渲染的了。

圖片描述

6 先加個頭部吧,禿頂太醜了

在componets文件夾下建立一個Header.vue, 並在App.vue中引入,

Header.vue

<template>
  <el-row>
    <el-col :span="24"
      <div class="head-wrap">Element</div>
    </el-col>
  </el-row>
</template>

<style scoped>
.head-wrap{

}
</style>

App.vue

<template>
  <div id="app">
    <el-container>
      <el-header class="header">
        <vheader />
      </el-header>
      <el-container>
        <el-aside width="200px">
          <navmenu></navmenu>
        </el-aside>
        <el-main>Main
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>
<script>
import NavMenu from '@/components/NavMenu'
import Header from '@/components/Header'

export default {
  name: 'app',
  components: {
    'navmenu': NavMenu,
    'vheader': Header
  }
}

</script>

<style>
.header {
  background-color: #409EFF;
  color: #fff;
  line-height: 60px;
}
</style>

這時候打開瀏覽器看看, 是否是已經好看一點了。可是body有邊框,很差看啊!
圖片描述

再次美化

安裝Normalize.css, vue-awesome

cnpm i normalize.css -D
cnpm i vue-awesome -D

這裏主要貼一下main.js的改動,其餘的代碼就不貼了:

import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import NormailizeCss from 'normalize.css'
import 'vue-awesome/icons'
import Icon from 'vue-awesome/components/Icon'

import App from './App'
import router from './router'

Vue.config.productionTip = false

Vue.use(ElementUI)
Vue.component('icon', Icon)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  template: '<App/>',
  components: { App }
})

看下效果, 圖標什麼的都有了。
圖片描述

7 組件路由與懶加載

在components新增四個文件:

BasicContainer.vue

<template>
  <div>
    這是:Container 佈局容器
  </div>
</template>

BasicLayout.vue

<template>
  <div>
    這是:Layout 佈局
  </div>
</template>

FormCheckbox.vue

<template>
  <div>
    這是:Checkbox 多選框
  </div>
</template>

FormRadio.vue

<template>
  <div>
    這是:Radio 單選框
  </div>
</template>

修改route/index.js文件, 關於路由和懶加載就不在此贅述,任何文檔都沒有官方文檔說的好。

注意:若是您使用的是 Babel,你將須要添加 syntax-dynamic-import 插件,才能使 Babel 能夠正確地解析語法。
也就是說,你要先安裝syntax-dynamic-import, 否則懶加載根本不行。

cnpm install --save-dev babel-plugin-syntax-dynamic-import
import Vue from 'vue'
import Router from 'vue-router'
import menus from '@/config/menu-config'

Vue.use(Router)

var routes = []

menus.forEach((item) => {
  item.sub.forEach((sub) => {
    routes.push({
      path: `/${sub.componentName}`,
      name: sub.componentName,
      component: () => import(`@/components/${sub.componentName}`)
    })
  })
})

export default new Router({ routes })

另外App.vue文件須要加上 router-view

<el-main>
  <router-view></router-view>
</el-main>

看看效果:點擊菜單,路徑跳轉,而且每次都是單獨去加載路由的文件。

圖片描述

8 github 部署

若是你想在github上部署,那麼你要修改config/index.js的如下代碼, 否則有些文件由於路徑問題可能會找不到。

build: {
    // Template for index.html
    index: path.resolve(__dirname, '../docs/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../docs'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/vue-el-dashboard/',

掃碼訂閱個人微信公衆號:洞香春天。天天一篇技術短文,讓知識再也不高冷。

相關文章
相關標籤/搜索