上篇文章(webpack+vue項目實戰(一,搭建運行環境和相關配置))搭建了好了基本的一個項目目錄,安好好了一些要用到的依賴,以及把項目跑了起來。接下來,咱們就進行第二步的操做,第二步就是作好一個開發系統的主頁面,這個頁面主要也就是一個側邊欄,經過側邊欄的各個選項來進行操做(切換各個組件)。好比回款管理,訂單管理,物流管理等等的操做。javascript
開始屬於排版這一塊了,是時候在index.js引入一個公用樣式了,至關於一個樣式重置表。css
需求有一個,頁面上面須要放一個退出的登陸按鈕,我就寫了一個頂部組件的文件。首先就是建立這個文件html
代碼以下vue
<template> <div class="topbar"> <el-button class="fr mr30 mt15" type="primary" size="small" @click="loginOut">退出登陸</el-button> </div> </template> <script> export default{ data(){ return { name: 'topbar' } }, methods: { loginOut(){ ... } }, mounted(){ } } </script> <style lang="scss" scoped> .topbar { width: 100%; height: 60px; } </style>
而後入口文件(index.js
)引用這個文件,而且在vue中註冊組件import topbarComponent from './../components/admin_base/topbar.vue';
java
而後入口模板文件,index.html引入標籤
頁面結果(基於上一篇文章,已經跑起來的結果)webpack
頁面上的class在公用樣式裏面有寫好樣式,還有一些樣式是element-ui提供的,
<el-button>退出登陸</el-button>
就是element-ui提供的組件,在入口文件index.js已經引入了element-ui。這裏直接用就好!web
這個比較簡單,我就很少說了。vue-router
這個側邊欄就是這篇文章的重點,也是整個項目操做的重點。先在目錄上建立這樣一個的側邊欄的組件文件。element-ui
下面圖片是咱們要實現的效果,那些排版切圖的樣式我很少說了,相信不會難倒你們segmentfault
從上面的效果圖的看到。有3個菜單(首頁,銷售消息通知,銷售管理)。並且首頁這個菜單能夠點擊,執行跳轉,其它兩個菜單又有子菜單,點擊只是一個子菜單顯示與隱藏的操做。
因此,側邊欄的數據確定是一個數組,而且是一個對象數組。每一個對象至少有四個屬性(要顯示的文字,跳轉的url,是否有子菜單,是否當前菜單)。而後對於有子菜單的菜單,要給一個屬性控制是否展開顯示子菜單,要一個屬性,儲存子菜單。
以下面文字
[ { 菜單名:'菜單名稱(首頁)', 跳轉的url:'url(/index)', 是否當前標識:'一個標誌string(0)', 是否有子菜單:'是否 true||false' }, { 菜單名:'菜單名稱(首頁)', 跳轉的url:'url(/index)', 是否當前標識:'一個標誌string(0)', 是否有子菜單:'true||false', 是否展現:'是否 true||false', 子菜單:[] } ]
對於子菜單,因爲沒有子菜單了,因此須要三個屬性(要顯示的文字,跳轉的url,是否當前標識:'一個標誌string(0)')就好。因爲子菜單不止一個,因此,子子菜單這個確定也是一個數組,每一個子菜單也有屬性,因此,也是一個對象屬性,因此,數據大概以下面。
[ { 菜單名:'菜單名稱 (首頁)', 跳轉的url:'url (/index)', 是否當前標識:'一個標誌string (0)', 是否有子菜單:'是否 true||false' }, { 菜單名:'菜單名稱 (首頁)', 跳轉的url:'url (/index)', 是否當前標識:'一個標誌string (1)', 是否有子菜單:'是否 true||false', 是否展現:'是否 true||false', 子菜單:[ { 菜單名:'菜單名稱 (首頁)', 跳轉的url:'url (/index)', 是否當前標識:'一個標誌string (1_1)' }, { 菜單名:'菜單名稱 (首頁)', 跳轉的url:'url (/index)', 是否當前標識:'一個標誌string (1_2)' } ] } ]
最後,整理出來的數據就是!(tag這個標識數據,是我本身起的,你們也能夠隨意起。這個標識在下面會用到,在這裏能夠暫時不關注)
data(){ return { currentTag: '0', menus: [ { name: '首頁', url: '/index', tag: '0', hasExtend: false, //是否有二級菜單 }, { name: '銷售消息通知', url: '/saleR', tag: 'sale', hasExtend: true, //是否有二級菜單 fold: true, //是否展開 extend: [ { name: '待確認訂單', url: '/order/list/0?ordConfirmStatus=0', tag: '1_1', }, { name: '待出庫物流', url: '/logistics/logisticsList/0', tag: '1_2' }, { name: '待發貨物流', url: '/logistics/logisticsList/1', tag: '1_3' }, { name: '待收貨物流', url: '/logistics/logisticsList/2', tag: '1_4' }, { name: '待確認回款', url: '/cash/cashList/0', tag: '1_5' }, { name: '待開票申請', url: '/invoice/invoiceWriteList/0', tagIndex: '1_6' } ] }, { name: '銷售管理', url: '/workbench', hasExtend: true, //是否有二級菜單 fold: true, //是否展開 extend: [ { name: '建立銷售單', url: '/order/create', tag: '2_1' }, { name: '銷售單管理', url: '/order/list', tag: '2_2' }, { name: '物流管理', url: '/logistics/logisticsList', tag: '2_3' }, { name: '回款管理', url: '/cash/cashList', tag: '2_4' }, { name: '開票管理', url: '/invoice/invoiceWriteList', tag: '2_9' }, { name: '票據管理', url: '/invoice/invoiceManageList', tag: '2_5' }, { name: '提成管理', url: '/commission/commissionList', tag: '2_6' }, { name: '提成設置', url: '/commission/commissionSet', tag: '2_7', }, { name: '合同管理', url: '/contract/contractList', tag: '2_8' }, ] }, ], } },
上面的數據相信你們都沒什麼問題,一一對應上就好(name--菜單名稱, url--跳轉的url,tag--當前的標識, hasExtend--是否有二級菜單,fold--是否展開extend--子菜單)
<template> <ul class="snav-menu" @click="show=false"> <li v-for="(item,index) in menus" :class="{active:item.fold,hasextend:item.hasExtend}"> <!--若是沒有二級菜單--> <!--若是遍歷到的標識等於當前的標識,就加上active類名,改變樣式--> <!--點擊事件爲觸發跳轉路由,就好比點擊‘首頁’,就是跳轉到‘首頁’的對應的路由--> <a v-if="!item.hasExtend" href="javascript:;" class="tit" @click="switchNav(item.url,item.tag)" :class="{active:item.tag==currentTag}"> <em>{{item.name}}</em> </a> <!--若是有二級菜單--> <!--點擊事件爲觸發子元素的顯示或隱藏 好比點擊‘銷售消息通知’,就觸發‘銷售消息通知’下面子菜單的顯示或者隱藏。若是顯示就隱藏,隱藏就顯示--> <a v-else href="javascript:;" class="tit" @click.stop="flod(index)"> <em>{{item.name}}</em> </a> <!--若是有二級菜單,遍歷子菜單--> <!--若是有二級菜單,而且fold屬性爲true(子菜單展開顯示)。就加上active類名,改變樣式--> <div class="extend-nav level2" v-if="item.hasExtend" :class="{active:item.fold}"> <p v-for="(extend1,deep1) in item.extend"> <!--若是遍歷到的標識等於當前的標識,就加上active類名,改變樣式--> <!--點擊切換路由(頁面的操做)--> <a href="javascript:;" :class="{active:extend1.tag==currentTag}" @click="switchNav(extend1.url,extend1.tag)"> <em>{{extend1.name}}</em> </a> </p> </div> </li> </ul> </template>
flod
和switchNav
這個兩個屬性你們暫時不須要關注,下面會用到
遍歷數據這個,你們看了上面的代碼和註釋,很好理解。我就很少說了!而後,在index.js裏面,引入和註冊這個組件。
而後index.html頁面引用
而後ctrl+s一下,就能夠看到效果了(前面在webpack.config.label.js
已經配置了熱刷新。因此直接就能夠看到效果,保存一下,或者改了一些代碼後,一段時間沒操做了,瀏覽器都會刷新,以下圖)
看到運行結果,側邊欄出來了。而後,下一步!
關於側邊欄的操做,比較簡單,無非就是點擊菜單,跳轉路由,標誌當前項以及菜單下面子菜單的顯示與隱藏。
1.首先,觸發路由的跳轉和標誌當前項
咱們用到的是是上面代碼的switchNav
這個方法;
咱們簡單分析一下,這個方法,要實現跳轉路由,標誌當前項。就必需要接收兩個參數(要跳轉路由的url,當前的標識)。下面就實現下
switchNav(url,tag){ //標識當前導航 this.currentTag = tag; //router導航 this.$router.push({ 'path': url, 'query': { "tag": tag } }); }
看着代碼是否是特別簡單,每次點擊的時候,用一個變量this.currentTag
記錄當前的tag
,在html
遍歷的時候,若是遍歷道的tag
等於currentTag
的話,就加上active
的類名,標誌當前項,不等於就不加類名。
好比一開始‘
this.currentTag='0'
,而後,首頁的tag
又是等於'0'
,因此遍歷道‘首頁’的時候,就會給‘首頁’那個菜單加上active
的類名’
而後跳轉路由那個沒有什麼能夠說的了,就把url當成參數傳進去而已。
2.最後,實現菜單下面子菜單的顯示與隱藏。這個方法就一行代碼。
//展開收起導航面板 flod(index){ this.menus[index].fold = !this.menus[index].fold; },
由於只有兩級,因此,只是根據傳進來的索引(index
)來操做menus這個數組而已,把要操做的項的fold屬性,取反。
運行一下,發現路由變了,當前項有標識了,子菜單的顯示與隱藏也有了!原理也很簡單。
運行完了,附上這個文件(snav-component.vue
)的代碼大概就是這樣
<template> <ul class="snav-menu" @click="show=false"> <li v-for="(item,index) in menus" :class="{active:item.fold,hasextend:item.hasExtend}"> <!--若是沒有二級菜單--><!--若是遍歷到的標識等於當前的標識,就加上active類名,改變樣式--> <a v-if="!item.hasExtend" href="javascript:;" class="tit" @click="switchNav(item.url,item.tag)" :class="{active:item.tag==currentTag}"> <em>{{item.name}}</em> </a> <!--若是有二級菜單--> <a v-else href="javascript:;" class="tit" @click.stop="flod(index)"> <em>{{item.name}}</em> </a> <!--若是有二級菜單,遍歷子菜單--><!--若是有二級菜單,而且fold屬性爲true(子菜單展開顯示)。就加上active類名,改變樣式--> <div class="extend-nav level2" v-if="item.hasExtend" :class="{active:item.fold}"> <p v-for="(extend1,deep1) in item.extend"> <!--若是遍歷到的標識等於當前的標識,就加上active類名,改變樣式--><!--點擊切換路由(頁面的操做)--> <a href="javascript:;" :class="{active:extend1.tag==currentTag}" @click="switchNav(extend1.url,extend1.tag)"> <em>{{extend1.name}}</em> </a> </p> </div> </li> </ul> </template> <script> export default{ data(){ return { //記錄當前的標識 currentTag: '0', menus: [ { name: '首頁', url: '/index', tag: '0', hasExtend: false, //是否有二級菜單 }, { name: '銷售消息通知', url: '/saleR', tag: 'sale', hasExtend: true, //是否有二級菜單 fold: true, //是否展開 extend: [ { name: '待確認訂單', url: '/order/list/0?ordConfirmStatus=0', tag: '1_1', }, { name: '待出庫物流', url: '/logistics/logisticsList/0', tag: '1_2' }, { name: '待發貨物流', url: '/logistics/logisticsList/1', tag: '1_3' }, { name: '待收貨物流', url: '/logistics/logisticsList/2', tag: '1_4' }, { name: '待確認回款', url: '/cash/cashList/0', tag: '1_5' }, { name: '待開票申請', url: '/invoice/invoiceWriteList/0', tagIndex: '1_6' } ] }, { name: '銷售管理', url: '/workbench', hasExtend: true, //是否有二級菜單 fold: true, //是否展開 extend: [ { name: '建立銷售單', url: '/order/create', tag: '2_1' }, { name: '銷售單管理', url: '/order/list', tag: '2_2' }, { name: '物流管理', url: '/logistics/logisticsList', tag: '2_3' }, { name: '回款管理', url: '/cash/cashList', tag: '2_4' }, { name: '開票管理', url: '/invoice/invoiceWriteList', tag: '2_9' }, { name: '票據管理', url: '/invoice/invoiceManageList', tag: '2_5' }, { name: '提成管理', url: '/commission/commissionList', tag: '2_6' }, { name: '提成設置', url: '/commission/commissionSet', tag: '2_7', }, { name: '合同管理', url: '/contract/contractList', tag: '2_8' }, ] }, ], } }, methods: { //切換組件 switchNav(url,tag){ //標識當前導航 this.currentTag = tag; //router導航 this.$router.push({ 'path': url, 'query': { "tag": tag } }); }, //展開收起導航面板 flod(index){ this.menus[index].fold = !this.menus[level1].fold; }, } } </script> <style lang="scss"> html,body,.zyl-admin-bd,.zyl-admin-wrap { width: 100%; height: 100%; } .zyl-admin-wrap{ position: fixed; } .zyl-admin-snav { position: fixed; z-index: 1; width: 210px; height: 100%; overflow-y: auto; background: #2a3542; box-shadow: 3px 0 30px rgba(0, 0, 0, .2); &::-webkit-scrollbar { width: 5px; height: 100%; border-radius: 2px; background: #424448; } &::-webkit-scrollbar-thumb { background: #A2A2A2; border-radius: 2px; } .snav-menu { margin-top: 10px; > li { margin:0 10px 10px 10px; &.hasextend { .tit { background: #35404d; } } &.active { background: #35404d; border-radius: 4px; overflow: hidden; .tit { background: #475669 !important; .icon-options-unfold { display: none; } .icon-options-fold { display: inline-block; } } .extend-nav { display: block; } } .tit { line-height: 22px; color: #aeb2b7; text-decoration: none; display: block; padding: 5px 0 5px 10px; font-size: 12px; outline: none; transition: all 0.3s ease; &:hover, &.active { background: #35404d; color: #fff; em { color: #FF6C60; } } em { display: inline-block; vertical-align: middle; font-style: normal; } } .extend-nav { display: none; &.active { display: block; } p { position: relative; a { display: block; font-size: 12px; padding: 6px 0; line-height: 25px; height: 25px; color: #aeb2b7; text-decoration: none; transition: all 0.3s ease; text-indent: 40px; &:hover, &.active { color: #FF6C60; background: #2e3844; .icon-arrow { display: inline-block; } } } } } } } } .zyl-admin-content { height: 100%; margin-left: 210px; overflow-y: auto; &::-webkit-scrollbar { width: 5px; height: 100%; border-radius: 2px; background: #424448; } &::-webkit-scrollbar-thumb { background: #A2A2A2; border-radius: 2px; } .wrapper { box-sizing: border-box; width: 100%; height: 100%; &::-webkit-scrollbar { width: 5px; height: 100%; border-radius: 2px; background: #424448; } &::-webkit-scrollbar-thumb { background: #A2A2A2; border-radius: 2px; } } } </style>
有一點要注意下,除了點擊首頁能看到一張圖片以外,點擊其它的菜單,右邊都是白色的一片。由於其它的菜單的url。並無對應的組件。
好比:這個url在路由裏面並無對應的組件。
怎麼知道?在上一篇文件說到的router.js裏面,並無配置‘/order/list/0?ordConfirmStatus=0
’這個url
對應的組件。因此在index.html
的<router-view></router-view>
輸出的就是空白的一片。如今這裏算是複習上一篇的內容了。也是給下一篇埋了一個伏筆。下一篇就講這個配置。
今天就到這裏了。主要就是一個主頁面,主要是側邊欄的一個開發。這個側邊欄就是根據控制錄用的變化。技術棧主要也就是vue
和vue-router
。原理就是根據路由的變化執行組件的切換。達到一個頁面跳轉的效果。下一篇就會說到,配置路由和路由對應的組件。但願能幫到你們。最後仍是那句老話-若是你們發現我哪裏寫錯了,或者是哪裏寫得很差,歡迎指點下。