項目搭建 + ⾸⻚布局實現
上篇對該項目做了個總述 :Vue + Element-ui實現后台管理系統(1) --- 總述
這篇主要講解 項目搭建 + 后台⾸⻚布局實現 :
整體效果


后台首頁按布局一共包含3個部分: 1、左側欄部分 2、頭部部分 3、內容部分。
說明
在整個后台管理系統中,左側欄和頭部部分是應該一直在頁面中展示的,所以對於每個頁面這兩個組件都應該存在,而 內容部分 才是通過router的跳轉而跳到不同的組件。
下面先把整個項目搭建一下,然后再來講解上面三個部分
一、項目搭建
1、環境搭建
#1、安裝node (node -v查詢版本號)
node 安裝
#2、安裝淘寶鏡像
npm install -g cnpm --registry=https://registry.npm.taobao.org
#3、安裝 webpack,以全局的方式安裝
npm install webpack -g
#4、全局安裝vue以及腳手架vue-cli
npm install @vue/cli -g --unsafe-perm
#5、創建vue項目 mall-manage-system是你起的項目名稱
vue create mall-manage-system
#6、運行當前項目 這個整個項目就搭建好了
npm run serve
在安裝中可能會存在的問題
2、npm install 報錯,提示 gyp ERR! stack Error: EACCES: permission denied 解決方法
2、項目初期搭建
如果上面都安裝成功,那么通過 npm run serve 就可用啟動該項目了。這里把簡單說明下一些公共配置
1、main.js(主文件)
import Vue from 'vue'
import App from './App.vue'
import router from './router' //引入 vue-router
import store from './store' //引入 vuex
// 全局配置
import '@/assets/scss/reset.scss' //全局樣式
import 'element-ui/lib/theme-chalk/index.css' //element-ui樣式
import http from '@/api/config' //axios
import './mock' // mockjs
// 第三方包
import ElementUI from 'element-ui'
Vue.use(ElementUI)
Vue.prototype.$http = http
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
2、router(路由跳轉配置)
router作用
:簡單理解就是幫助組件之間跳轉用的。
這里為了性能都采用懶加載,還有這里不管先登陸登陸頁面 默認跳轉組件為 Main.vue
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// 完整路由代碼
export default new VueRouter({
routes: [
{
path: '/',
component: () => import('@/views/Main'),
children: [
{
path: '/',
name: 'home',
component: () => import('@/views/Home/Home'),
},
{
path: '/user',
name: 'user',
component: () => import('@/views/UserManage/UserManage'),
},
{
path: '/mall',
name: 'mall',
component: () => import('@/views/MallManage/MallManage'),
},
{
path: '/page1',
name: 'page1',
component: () => import('@/views/Other/PageOne'),
},
{
path: '/page2',
name: 'page2',
component: () => import('@/views/Other/PageTwo'),
},
]
}
]
})
3、vuex(存儲共享數據)
vuex作用
:vuex解決了組件之間同一狀態的共享問題。
export default {
//存儲數據
state: {
isCollapse: false
},
//調用方法
mutations: {
collapseMenu(state) {
state.isCollapse = !state.isCollapse
}
},
actions: {}
}
這里先只設定一個全局數據isCollapse,用於側邊欄是否水平展開。
4、axios
axios作用
:axios主要是用於向后台發起請求的,還有在請求中做更多是可控功能。
import axios from 'axios'
// 創建一個axios實例
const service = axios.create({
// 請求超時時間
timeout: 3000
})
export default service
其它的這里就不詳細講解了,在文章最下面會附上github地址
二、Main.vue
這個是后台系統的主組件,它采用的布局是 element-ui的 Container 布局容器 Container 布局容器
<template>
<el-container style="height: 100%">
<!--左側欄-->
<el-aside width="auto">
<!--左側欄控件-->
<common-aside></common-aside>
</el-aside>
<!--右側欄-->
<el-container>
<!--header部分-->
<el-header>
<!--header部分控件-->
<common-header></common-header>
</el-header>
<el-main>
<!--左側欄 和 header部分對於整個后台部分都是不變的,唯一變的就是上面3的部分,這里就通過router-view來展示所需控件-->
<router-view/>
</el-main>
</el-container>
</el-container>
</template>
<script>
import CommonAside from '../components/CommonAside'
import CommonHeader from "../components/CommonHeader";
export default {
components: {
CommonAside,
CommonHeader
}
}
</script>
這樣整個后台管理系統的整個輪廓就定下來了,接下來通過路由的切換的組件展示在router-view
的位置。
三、左側欄部分(CommonAside.vue)
它采用的布局是 element-ui的 NavMenu 導航菜單
<template>
<!--collapse 是否水平折疊收起菜單-->
<el-menu
:collapse="isCollapse"
:default-active="$route.path"
class="el-menu-vertical-demo"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<!--是否水平折疊收起菜單 會影響這里字段的顯示 -->
<h3 v-show="isCollapse">偶囧</h3>
<h3 v-show="!isCollapse">偶囧后台管理系統</h3>
<el-menu-item :index="item.path" v-for="item in noChildren" :key="item.path" @click="clickMenu(item)">
<i :class="'el-icon-' + item.icon"></i>
<span slot="title">{{ item.label }}</span>
</el-menu-item>
<el-submenu :index="item.label" v-for="(item, index) in hasChildren" :key="index">
<template slot="title">
<i :class="'el-icon-' + item.icon"></i>
<span slot="title">{{ item.label }}</span>
</template>
<el-menu-item-group>
<el-menu-item :index="subItem.path" v-for="(subItem, subIndex) in item.children" :key="subIndex" @click="clickMenu(subItem)">
<i :class="'el-icon-' + subItem.icon"></i>
<span slot="title">{{ subItem.label }}</span>
</el-menu-item>
</el-menu-item-group>
</el-submenu>
</el-menu>
</template>
<script>
export default {
//計算屬性
computed: {
//沒有子菜單
noChildren() {
return this.menu.filter(item => !item.children)
},
//有子菜單 (這樣設置會有一個問題 就是有子菜單的 永遠會在沒有子菜單的下面)
hasChildren() {
return this.menu.filter(item => item.children)
},
isCollapse() {
// 這里的數據就是從vuex取得
return this.$store.state.tab.isCollapse
}
},
data() {
return {
menu: [
{
path: '/user',
name: 'user',
label: '用戶管理',
icon: 'user',
url: 'UserManage/UserManage'
},
{
label: '其他',
icon: 'location',
children: [
{
path: '/page1',
name: 'page1',
label: '頁面1',
icon: 'setting',
url: 'Other/PageOne'
},
{
path: '/page2',
name: 'page2',
label: '頁面2',
icon: 'setting',
url: 'Other/PageTwo'
}
]
}
]
}
},
methods: {
//跳轉路由 根據名稱跳轉
clickMenu(item) {
this.$router.push({ name: item.name })
}
}
}
</script>
四、header部分(CommonHeader.vue)
這里通過點擊那個圖標來控制:左側欄是否水平折疊收起菜單,所以這里來修改vuex中 isCollapse 數據。
它采用的布局是 element-ui的 Dropdown 下拉菜單
<template>
<header>
<div class="l-content">
<el-button plain icon="el-icon-menu" size="mini" @click="collapseMenu"></el-button>
<h3 style=" color : #fff">首頁</h3>
</div>
<div class="r-content">
<el-dropdown trigger="click" size="mini">
<span class="el-dropdown-link"><img :src="userImg" class="user"/></span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>個人中心</el-dropdown-item>
<el-dropdown-item @click.native="logOut">退出</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</header>
</template>
<script>
export default {
data() {
return {
userImg: require('../assets/images/user.png')
}
},
methods: {
//控制左側菜單是否折疊
collapseMenu() {
this.$store.commit('collapseMenu')
},
//退出登陸
logOut() {
location.reload()
}
}
}
</script>
五、Home.vue
它采用的布局是 element-ui的 Card 卡片 + Layout 布局
<template>
<el-row class="home" :gutter="20">
<!--span默認一共是24,這里占8 下面占16,所以這兩個分隔欄所占的寬度 是1:2-->
<el-col :span="8" style="margin-top: 20px">
<!--shadow屬性設置卡片陰影出現的時機-->
<el-card shadow='hover'>
<div class="user">
<img :src="userImg"/>
<div class="userinfo">
<p class="name">Admin</p>
<p class="access">超級管理員</p>
</div>
</div>
<div class="login-info">
<p>上次登錄時間:<span>2019-10-20</span></p>
<p>上次登錄地點:<span>北京</span></p>
</div>
</el-card>
<el-card style="height: 460px ; margin-top: 20px">
<el-table :data="tableData">
<el-table-column show-overflow-tooltip v-for="(val, key) in tableLabel" :key="key" :prop="key"
:label="val"></el-table-column>
</el-table>
</el-card>
</el-col>
<el-col :span="16" style="margin-top: 20px">
<div class="num">
<el-card shadow="hover" v-for="item in countData" :key="item.name" :body-style="{ display: 'flex', padding: 0}">
<i class="icon" :class="`el-icon-${item.icon}`" :style="{ background: item.color }"></i>
<div class="detail">
<p class="num">¥ {{ item.value }}</p>
<p class="txt">{{ item.name }}</p>
</div>
</el-card>
</div>
<el-card shadow="hover" style="height: 280px">
</el-card>
<div class="graph">
<el-card shadow="hover" style="height: 260px">
</el-card>
<el-card shadow="hover" style="height: 260px">
</el-card>
</div>
</el-col>
</el-row>
</template>
<script>
export default {
data() {
return {
userImg: require('../../assets/images/user.png'),
countData: [],
tableData: [],
tableLabel: {
name: '課程',
todayBuy: '今日購買',
monthBuy: '本月購買',
totalBuy: '總購買'
}
}
},
methods: {
getTableData() {
this.$http.get('/home/getData').then(res => {
res = res.data
this.tableData = res.data.tableData
})
}
},
//一進組件就會去請求后端接口 獲取首頁數據
created() {
this.getTableData()
}
}
Github地址
mall-manage-system
別人罵我胖,我會生氣,因為我心里承認了我胖。別人說我矮,我就會覺得好笑,因為我心里知道我不可能矮。這就是我們為什么會對別人的攻擊生氣。
攻我盾者,乃我內心之矛(13)