头部
退出功能
默认头像
// 短路写法
<img :src="userInfo.user_pic || defImg" alt="" class="avatar" />
// 三元运算符
<img :src="userInfo.user_pic?userInfo.user_pic : defImg" alt="" class="avatar" />
<script>
// 导入一个图片
import defImg from '@/assets/logo.png'
export default {
name: 'Main',
data () {
return {
// 赋值到data变量中 键值对一样可以简写
defImg
}
}
</script>
获取登录用户信息,渲染到页面
配置请求
// 获取登录人信息
export function getUserInfoApi () {
//这里没有传入需要的参数,因为可以请求拦截器中统一配置
return request.get('/my/userinfo')
}
// 在子模块中导入该函数,并再次封装
import { loginApi, getUserInfoApi } from '@/Api/index'
export default {
// 开启命名空间
namespaced: true,
actions: {
async getUserInfo () {
await getUserInfoApi()
}
}
}
created () {
// 直接访问user模块的getUserInfo方法
this.$store.dispatch('user/getUserInfo')
}
发送请求之后发现请求为401 ( Unauthorized 译为 未授权的)
这种情况一般是缺少验证信息,因为这里没有配置请求头里的token
配置请求头
// axios网站复制
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 箭头函数写法
axios.interceptors.request.use( (config) => {
// 发送请求之前执行代码
return config
})
config参数:控制台输出可以看到
添加请求头config.headers = token(具体什么名,看接口文档)
token存储在vuex中,js中调用vuex的数据,需要导入vuex实例
导入后的实例相当于组件中的this.$store
给添加请求头加一个判断,/my开头的接口需要token请求
config.url可以拿到请求接口,使用startsWitn方法判断uel是不是/my开头的
// 导入vuex的实例
import Store from '@/store/index'
import axios from 'axios'
// 定义新axios实例
const request = axios.create({
// 配置跟路径
baseURL: 'http://big-event-vue-api-t.itheima.net'
})
// 导出新实例
export default request
// 配置请求拦截器
request.interceptors.request.use((config) => {
console.log(config)
// /my开头的接口需要token请求,所以使用startsWitn判断uel是不是/my开头的
if (config.url.startsWith('/my')) {
// store 是vuex实例
// state.模块名.state变量
config.headers.Authorization = Store.state.user.token
}
// 返回请求配置,不然外面获取不到服务器发送过来的数据
return config
})
将获取到的用户信息存储,渲染到页面中
// 用户模块中 定义一个state变量用来存储用户信息
export default {
// 开启命名空间
namespaced: true,
state: {
userInfo: {}
},
mutations: {
// 存贮用户数据
setuserInfo (state, payload) {
state.userInfo = payload
}
},
// 组件中 mapState 导入模块中的变量到computed,在页面渲染
import { mapState } from 'vuex'
computed: {
...mapState('user', ['userInfo'])
},
左侧菜单
<el-menu
default-active="1"
class="el-menu-vertical-demo"
background-color="#23262E"
text-color="#fff"
active-text-color="#409EFF"
unique-opened
>
<!-- 不包含子菜单的“一级菜单” -->
<el-menu-item index="1"><i class="el-icon-s-tools"></i>一级菜单</el-menu-item>
<!-- 包含子菜单的“一级菜单” -->
<el-submenu index="2">
<template slot="title">
<i class="el-icon-s-tools"></i>
<span>一级菜单</span>
</template>
<el-menu-item index="2-1"><i class="el-icon-star-on"></i>二级菜单</el-menu-item>
<el-menu-item index="2-2"><i class="el-icon-star-on"></i>二级菜单</el-menu-item>
<el-menu-item index="2-3"><i class="el-icon-star-on"></i>二级菜单</el-menu-item>
</el-submenu>
</el-menu>
选中高亮
element组件不支持,在页面中查找到当前选中的元素类名,覆盖样式
需要加上最高权重不然不会覆盖!important
.el-aside {
background-color: #23262e;
.el-menu-item.is-active,
// 鼠标移入也高亮
.el-menu-item:hover {
background: orange !important;
color: #fff !important;
// 图标颜色
i {
color: #fff;
}
}
}
获取菜单数据并渲染
获取数据
import request from '@/utils/request'
// 写法1
// export function getMenu () {
// return request.get('/my/menus')
// }
// 写法2
export const getMenu = () => request.get('/my/menus')
//导入封装的请求
import { getMenuApi } from '@/Api/menu'
export default {
name: 'Main',
data () {
return {
menus: []
}
},
methods: {
// 定义获取菜单方法
async getMenu () {
// 解构
const { data } = await getMenuApi()
console.log(data)
// 获取到的变量赋值
this.menus = data.data
}
},
created () {
this.getMenu()
}
}
动态渲染菜单
- 有两种情况
- 1.不包含子菜单一级菜单
- 2.包含子菜单的一级菜单
- 需要再
<templat>
空标签来v-for(打包的时候 html页面不解析)- 同时使用 v-if 来判断
- 如果循环的是第一种那么第二种的表标签就隐藏
- 如果循环的是第二种那么第一种的表标签就隐藏
- children是null (false) ,取反为true,就会循环第一个了,children有值结果为true,取反后false不满足if条件就循环第二个了
<el-menu
default-active="1"
class="el-menu-vertical-demo"
background-color="#23262E"
text-color="#fff"
active-text-color="#409EFF"
unique-opened
router
>
<template v-for="item in menus">
<!-- 不包含子菜单的“一级菜单” -->
<el-menu-item
v-if="!item.children"
:key="item.indexPath"
:index="item.indexPath"
><i :class="item.icon"></i>{{ item.title }}</el-menu-item
>
<!-- 包含子菜单的“一级菜单” -->
<el-submenu v-else :key="item.indexPath" :index="item.indexPath">
<template slot="title">
<i :class="item.icon"></i>
<span>{{ item.title }}</span>
</template>
<el-menu-item
v-for="child in item.children"
:key="child.indexPath"
:index="child.indexPath"
><i :class="child.icon"></i>{{ child.title }}</el-menu-item
>
</el-submenu>
</template>
</el-menu>
- 同时使用 v-if 来判断