猛犸系统-主页功能开发
主页功能开发
Flex布局
采用Flex布局得元素,成为Flex容器,简称容器。它得所有子元素自动成为容器成员,成为Flex项(Flex item)
Flex布局有两个轴,主轴和侧轴(cross,交叉轴)。
默认X为主轴,从左向右;侧轴Y轴,垂直向下。默认线性沿着主轴排列,不换行。
- justify-content 设置主轴上子元素排列方式
- flex-start 默认值,沿着主轴排列。如果主轴是row,子元素从左至右排列
- flex-end 从右开始对齐
- center 子元素居中对齐
- space-around 平分剩余空间
- space-between 先两边贴边,再平分剩余空间(重要)
- align-items 设置侧轴上的子元素的排列方式(单行)
- 控制一行元素侧轴上的排列效果
- flex-start 从头开始
- flex-end 从尾开始
- center 居中
- stretch 沿着侧轴拉伸,子元素不要给高度
div a中增加2个div b和c,默认div是block,所以这b、c是各占一行。a采用flex后,b、c称为Flex item,并挤在一起了。默认所有子元素按照行从左开始排列,默认不折行。
主页布局
背景参考可以i参考:https://preview.pro.ant.design/dashboard/analysis/
参考 https://element.eleme.cn/#/zh-CN/component/container,选择一个合适的布局
<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>
主页组件
src/plugins/element.js
import Vue from 'vue'
import { Form, FormItem, Input, Button, Message, Container, Header, Aside,
Main } from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css' // UI组件样式
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
Vue.use(Button)
Vue.use(Container)
Vue.use(Header)
Vue.use(Aside)
Vue.use(Main)
// 全局导入
Vue.prototype.$message = Message
scr/Views/HomeViews.vue
在Header中增加2个div,一个放logo,一个放退出按钮
<template>
<el-container>
<el-header>
<div class="logo">
<img src="../assets/logo.png" alt="logo" />
<div class="title">马哥教育猛犸运维系统管理平台</div>
</div>
<div class="info">
<el-button type="info" @click="logout">退出</el-button>
</div>
</el-header>
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-main>Main</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
methods: {
logout() {
window.localStorage.removeItem('token')
this.$router.push('/login')
}
}
}
</script>
<style lang="less" scoped>
.el-container {
height: 100%;
}
.el-header {
display: flex;
justify-content: space-between;
.logo {
display: flex;
img {
width: 30px;
height: 30px;
margin-top: 15px;
}
.title {
font-size: 24px;
margin-left: 5px;
margin-top: 15px;
}
i {
font-size: 30px;
margin-top: 15px;
}
}
}
.el-aside {
background-color: #112233;
}
.el-button {
margin-top: 10px;
}
.el-main {
background-color: #f0f2f4;
}
.el-menu {
border-right: none;
}
</style>
侧边栏菜单布局
src/plugins/element.js
import Vue from 'vue'
import { Form, FormItem, Input, Button, Message, Container, Header, Aside,
Main, Menu, MenuItem, Submenu } from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css' // UI组件样式
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
Vue.use(Button)
Vue.use(Container)
Vue.use(Header)
Vue.use(Aside)
Vue.use(Main)
Vue.use(Menu)
Vue.use(MenuItem)
Vue.use(Submenu)
// 全局导入
Vue.prototype.$message = Message
侧栏导航菜单 https://element.eleme.cn/#/zh-CN/component/menu#ce-lan
基本嵌套结构
<el-menu default-active="2-2">
<el-submenu index="1">
<template slot="title"><i class="el-icon-menu"></i>导航一</template>
<el-menu-item index="1-1">修改密码</el-menu-item>
<el-menu-item index="1-2">用户列表</el-menu-item>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-menu"></i>导航二</template>
<el-menu-item index="2-1">修改密码</el-menu-item>
<el-menu-item index="2-2">用户列表</el-menu-item>
</el-submenu>
</el-menu>
src/Views/HomeView.vue
<template>
<el-container>
<el-header>
<div class="logo">
<img src="../assets/logo.png" alt="logo" />
<div class="title">马哥教育猛犸运维管理平台</div>
<i :class="isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'" @click="isCollapse = !isCollapse"></i>
</div>
<div class="info">
<el-button type="primary" @click="logout">退出</el-button>
</div>
</el-header>
<el-container>
<el-aside :width="isCollapse ? '64px' : '240px'">
<el-menu
router
default-active="101"
background-color="#123"
text-color="#fff"
active-text-color="#ffd04b"
:collapse="isCollapse"
>
<el-submenu :index="item.id + ''" v-for="item in menuList" :key="item.id">
<template slot="title">
<i class="el-icon-menu"></i>
<span>{{ item.name }}</span>
</template>
<el-menu-item :index="sub.path" v-for="sub in item.children" :key="sub.id">
{{ sub.name }}
</el-menu-item>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main>
<!-- 嵌套路由 呈现 子组件的地方 -->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
created() {
// 生命周期钩子函数。该组件js内存中的实例对象被创建出来
this.getMenuList()
},
data() {
return {
menuList: [],
isCollapse: false
}
},
methods: {
logout() {
window.localStorage.removeItem('token')
this.$router.push('/login')
},
async getMenuList() {
// const {data:response} = await this.$http.get('xxx/', {
// params: {a:1, b:2},
// headers: {'Authorization': 'Bearer ' + window.localStorage.getItem('token')},
// }) // 需要token
const { data: response } = await this.$http.get('users/menulist/') // token header
console.log(response)
this.menuList = response
}
}
}
</script>
<style lang="less" scoped>
.el-container {
height: 100%;
}
.el-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 5px;
.logo {
display: flex;
align-items: center;
img {
height: 32px;
}
.title {
font-size: 24px;
margin-left: 5px;
}
i {
font-size: 30px;
margin-left: 5px;
}
}
}
.el-aside {
background-color: #123;
}
.el-main {
background-color: #f0f2f4;
}
.el-menu {
border-right: none;
}
</style>
左边栏菜单内容可以客户端写死,也可以从服务端动态获取。
从服务端获取,可以先认证用户后,根据用户的权限,返回菜单项。
axios拦截器
前端通过token判断是否登录,但是更多得数据时服务器端返回得,当浏览器端发请求到服务器端,服务器端必须能认证身份,那么浏览器端必须在请求得Header中增加Authorization字段。
文档:https://www.kancloud.cn/yunye/axios/234845
策略:只要向服务器端发请求,想获取数据,就必须进行token认证。
src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'
import './assets/css/main.css'
import axios from 'axios'
// axios全局设置
// 全局拦截器,只要发起异步请求都要带上这个token
axios.interceptors.request.use(config => {
config.headers.Authorization = 'Bearer ' + window.localStorage.getItem('token')
return config
})
// baseURL指向后台服务
axios.defaults.baseURL = '/api/v1/' // 代理到'http://127.0.0.1:8000/'
// 为Vue类增加全局属性$http,这样所有组件实例都可以使用该属性了
Vue.prototype.$http = axios
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')