公司最近項目是后台管理系統,由我負責,網上找模板發現還需要改很多地方,而且那些模板也沒有寫代碼的實現思路,對於vue項目經驗不足者很難看懂,所以就按照自己的思路從零實現一遍,過程講解還是比較詳細的,若是有不足之處還請指正。
整體布局:
登錄:
菜單:

准備工作:
1、安裝elementui
npm i element-ui -S import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' Vue.use(ElementUI)
2、配置路由
index.js:
import Vue from 'vue' import VueRouter from 'vue-router' const Home = () => import('../views/home/Home.vue') const Login = () => import('../views/login/Login.vue') Vue.use(VueRouter) const routes = [ { path: '/', name: 'Login', component: Login }, { path: '/home', name: 'Home', component: Home }, ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
3.開始寫組件
一、登錄login
<template>
<div class="login-wrap">
<el-form class="login-form" label-position="top" label-width="80px" :model="formdata"
>
<h2>用戶登錄</h2>
<el-form-item label="用戶名">
<el-input v-model="formdata.username"></el-input>
</el-form-item>
<el-form-item label="密碼">
<el-input v-model="formdata.password"></el-input>
</el-form-item>
<el-button class="login-btn" type="primary">登錄</el-button>
</el-form>
</div>
</template>
<script> export default { name: "Login", data() { return { formdata: { username: "", password: "", }, }; }, }; </script>
使用el-form表單進行布局,label-position="top"表示表單域標簽的位置是上下對齊,:model="formdata"表示我們要綁定的數據
看渲染效果
調整樣式:
<style scoped> .login-wrap { height: 100%; background: #324152; display: flex; justify-content: center; align-items: center;
} .login-form { width: 400px; background: #fff; border-radius: 5px; padding: 30px;
} .login-btn { width: 100%;
}
樣式調整好之后開始用aioxs發送登錄請求
安裝axios,
npm i axios -s
在main.js中引入
login.vue中使用:
methods:{ handleLodin(){ //測試版本
// if(this.formdata.username !== '' && this.formdata.password !== ''){
// this.$router.push({path:'/home'})
// // 2.提示成功
// this.$message({
// showClose: true,
// message: '登錄成功',
// type: 'success'
// });
// }else {
// this.$message({
// showClose: true,
// message: '用戶名和密碼不能為空',
// type: 'error'
// });
// }
//正式版本需要發送請求
//url是要發送請求的地址
this.$http.post('url',this.formdata).then(res => { //請求返回來的數據
console.log(res) // 保存token:
localStorage.setItem('token',res.data.token) // 登錄成功
if(res.data.status === 200){ // 1.跳轉home頁面
this.$router.push({path:'/home'}) // 2.提示成功
this.$message({ showClose: true, message: '登錄成功', type: 'success' }); }else { // 登錄失敗
this.$message({ showClose: true, message: '用戶名或密碼錯誤', type: 'error' }); } }) } }
當點擊登錄按鈕的時候會觸發handleclick事件,然后發送axios請求,如果登錄成功就跳轉到下一個頁面,顯示登錄成功的提示消息,如果失敗就拋出錯誤提示消息。這里我寫了兩個版本,一個是正式發送請求,一個是測試版本,在沒有后端接口的時候可以通過這個測試版本測試拋出的登錄成功和失敗消息提示。
對於燈枯成功和失敗的條件可以根據實際項目情況進行修改。
二、菜單menu
首先:布局分為三部分,頭部header,側邊欄aside,右邊主體,用elementui布局如下
<template>
<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>
</template>
<script> export default { name: 'Home' }; </script>
接下來我們給頁面加樣式:
<template>
<el-container class="container">
<el-header class="header"> header </el-header>
<el-container>
<el-aside class="aside">
<!-- 側邊欄導航 --> aside </el-aside>
<el-main class="main">Main</el-main>
</el-container>
</el-container>
</template>
<script> export default { name: "Home" }; </script>
<style scoped> .container { height: 100vh; font-size: 15px;
} .header { background: #212121; color: #fff;
} .aside { background: #3a3a3a; color: #fff;
/* height: 100%; */
} .main {
/* height: 100%; */ color: #212121;
}</style>
看看效果:
接着頭部樣式布局:通過24分欄進行布局。
將頭部分為兩部分,左邊占16欄,右邊占8欄el-row表示一行,el-col表示列
<el-row>
<el-col :span="16" class="headerlogo">
<div class="grid-content bg-purple">
<img style="width:400px;height: 30px" src="../../assets/img/top.png" alt="無法顯示圖片"
/>
</div>
</el-col>
<el-col :span="8" class="rightsection">
<div class="grid-content bg-purple-light">
<span class="el-dropdown-link userinfo-inner">歡迎您,管理員</span>
<span class="userinfo-inner" @click="signout">退出</span>
</div>
</el-col>
</el-row>
側邊欄布局:側邊欄是菜單menu,在elementui中用el-menu標簽來布局:
el-menu定義了當前的導航菜單及屬性,el-submenu定義了子菜單欄,el-menu-item-group定義了菜單分組,el-menu-item為具體的菜單項,組件從上到下分別是:el-menu, el-submenu, el-menu-item-group, el-menu-item。
<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" disabled>
<i class="el-icon-document"></i>
<span slot="title">導航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">導航四</span>
</el-menu-item>
</el-menu>
合並代碼:
<template>
<el-container class="container">
<el-header class="header">
<el-row>
<el-col :span="16" class="headerlogo">
<div class="grid-content bg-purple">
<img style="width:400px;height: 30px" src="../../assets/img/top.png" alt="無法顯示圖片"
/>
</div>
</el-col>
<el-col :span="8" class="rightsection">
<div class="grid-content bg-purple-light">
<span class="el-dropdown-link userinfo-inner">歡迎您,管理員</span>
<span class="userinfo-inner" @click="signout">退出</span>
</div>
</el-col>
</el-row>
</el-header>
<el-container>
<el-aside class="aside">
<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" disabled>
<i class="el-icon-document"></i>
<span slot="title">導航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">導航四</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main class="main">Main</el-main>
</el-container>
</el-container>
</template>
<script> export default { name: "Home", methods: { //退出
signout() { this.$confirm("退出登錄, 是否繼續?", "提示", { confirmButtonText: "確定", cancelButtonText: "取消", type: "warning", }).then(() => { this.$router.push({ path: "/" }); }); }, }, }; </script>
<style scoped> .container { height: 100vh; font-size: 15px;
} .header { background: #212121; color: #fff;
} .aside { background: #3a3a3a; color: #fff;
/* height: 100%; */
} .main {
/* height: 100%; */ color: #212121;
} .headerlogo { line-height: 60px; margin-top: 10px;
} .rightsection { line-height: 60px; text-align: center;
}
</style>
看效果:
但是我們的項目並沒有分組,所以不需要el-menu-item-group,進行修改:
<el-aside class="aside">
<!-- unique-opened只展開一個 -->
<!-- router開啟路由模式 -->
<el-menu :unique-opened="true" :router="true" background-color=" #3A3A3A" text-color="#fff" active-text-color="#ffd04b"
>
<!-- index 唯一標志 -->
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>企業信息管理</span>
</template>
<!-- index 表示跳轉路徑 后面需要改成路徑-->
<el-menu-item index="1-1">企業信息</el-menu-item>
</el-submenu>
<el-submenu index="2">
<template slot="title">
<i class="el-icon-location"></i>
<span>崗位信息管理</span>
</template>
<el-menu-item index="1-1">崗位信息</el-menu-item>
</el-submenu>
<el-submenu index="3">
<template slot="title">
<i class="el-icon-location"></i>
<span>訂單信息管理</span>
</template>
<el-menu-item index="1-1">訂單信息</el-menu-item>
</el-submenu>
<el-submenu index="3">
<template slot="title">
<i class="el-icon-location"></i>
<span>數據字典</span>
</template>
<el-menu-item index="1-1">崗位類型</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
- el-submenu index="1" 這個index表示每一組的唯一標志,當我們定義了 unique-opened=true的時候會根據這個表示展示相應的選項。自己可以測試一下把所有的選項組的index都設置成同一個值得時候是什么效果就明白了這個標志得作用。
- el-menu-item index="1-1",這個index值會被作為跳轉路徑進行跳轉,我們需要把這個值和頁面路徑對應起來。所以需要開啟路由模式,點擊那個頁面的時候左側就會顯示哪個頁面內容信息。
data() { return { menuData: [ { name: "企業信息管理", order: "1", path:'componyinfomanage', children: [ { path: "componyinfomanage", name: "企業信息", }, ], }, { path: "postinfomange", name: "崗位信息管理", order: "2", children: [ { path: "postinfomange", name: "崗位信息", }, ], }, { path: "orderinfomange", name: "訂單信息管理", order: "3", children: [ { path: "orderinfomange", name: "訂單信息", }, ], }, { path: "datamangeinfo", name: "數據字典", order: "4", children: [ { path: "datamangeinfo", name: "崗位類型", }, ], }, ], }; },
v-for循環顯示menuData
<el-aside class="aside">
<!-- 側邊欄導航 -->
<!-- unique-opened只展開一個 -->
<!-- router開啟路由模式 -->
<el-menu :unique-opened="true" :router="true" class="menu" background-color=" #3A3A3A" text-color="#fff" active-text-color="#ffd04b"
>
<el-submenu :index="' '+item1.order" v-for="(item1,index) in menuData" :key="item1.path">
<!--表示可以展開的一組 -->
<template slot="title" @click="clickTitle">
<!--圖標 -->
<i class="el-icon-location"></i>
<!--文字 -->
<span>{{item1.name}}</span>
</template>
<el-menu-item class="menuItem" @click="clickMenuItem" v-for="(item2,index) in item1.children" :key="item2.path" :index="item2.path"
>
<i class="el-icon-location"></i>
<!--圖標 -->
<span>{{item2.name}}</span>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
上面說過 el-menu-item 的index會替換成我們實際需要跳轉的路徑,那么就需要進行路由配置:
import Vue from 'vue' import VueRouter from 'vue-router' const Home = () => import('../views/home/Home.vue') const Login = () => import('../views/login/Login.vue') const ComponyInfoManage = () => import('../../src/views/componyinfo/ComponyInfoManage.vue') const PostInfoManage = () => import('../../src/views/postinfo/PostInfoManage.vue') const OrderInfoManage = () => import('../../src/views/orderinfo/OrderInfoManage.vue') const PostType = () => import('../views/datadictionary/DataDictionary.vue') Vue.use(VueRouter) const routes = [ { path: '/', name: 'Login', component: Login }, { path: '/home', name: 'Home', component: Home, children:[ { path: '/componyinfomanage', name: '企業信息', component: ComponyInfoManage, }, { path: '/postinfomange', name: '崗位信息', component: PostInfoManage, }, { path: '/orderinfomange', name: '訂單信息', component: OrderInfoManage, }, { path: '/datamangeinfo', name: '訂單信息', component: PostType, }, ] }, ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
注意,menuData中的path要和路由跳轉的path相同,不然跳轉的時候會找不到對應的頁面。
此時顯示如下:
至此,登錄+側邊菜單欄全部實現。
項目整體代碼放到了我的github上面,若是對你有一點幫助,還請賞個star[抱拳]