06-首页(渲染左侧菜单栏)
1.1-发送ajax请求左侧菜单栏
- Main.vue
-
<script> export default { name: "Main", data() { return { menus:[] }; }, async created() { //提交actions:异步请求用户信息 this.$store.dispatch("initUserInfo") //发送ajax请求菜单栏 const { data: res } = await this.$axios.get('/my/menus') console.log(res) //成功之后绑定到data if( res.code == 0 ){ this.menus = res.data }else{ this.$message.error('获取菜单失败!') } }, methods: { logout() { this.$confirm("您确认退出登录吗?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" }).then(() => { // 1. 清空 token this.$store.commit("updateToken", ""); // 2. 跳转到登录页面 this.$router.push("/login"); }) } } }; </script>
1.2-渲染用户个人信息
- 1.给Main.vue添加一个计算属性,用于简化vuex代码
-
computed:{ userInfo(){ return this.$store.state.userInfo } }, - 左侧菜单栏 + 右侧个人信息
1.3-渲染左侧菜单栏
-
难点分析
- (1)如果el-menu没有二级菜单就是el-menu-item
- (2)如果el-menu有二级菜单就是el-submenu
- (3)服务器返回的数组, 有一个children属性。 如果这个属性为空,就代表没有二级菜单。如果是一个数组就代表有二级菜单。
-
思路分析
- (1)也就说,这个数组在使用v-for指令的时候。无法确定到底要生成哪一个标签。需要根据数组的元素来判断。
- (2)解决方案:使用template标签包裹,根据条件来判断到底要渲染哪一个元素
-
举一反三:只要v-for指令渲染的标签是不固定的,就可以使用template标签进行包裹后渲染
-
核心结构如下
-
<template v-for=""> <!-- 下面两个组件二选一渲染 --> <组件a v-if="条件"></组件a> <组件b v-else></组件b> </template> -
逻辑类似于js中的这种逻辑
- 其实就是一个v-for嵌套一个v-if v-else
-
for(let i = 1;i<=10;i++){ if( i % 2 == 0){ console.log('我要生成el-menu-item') }else{ console.log('我要生成el-submenu') } }
-
-
Main.vue左侧菜单栏
-
default-active="/home"
- 设置菜单栏默认/home对应的页面高亮
-
<!-- 左侧菜单 -->
<el-menu
default-active="/home"
class="el-menu-vertical-demo"
background-color="#23262E"
text-color="#fff"
active-text-color="#409EFF"
unique-opened
router
>
<!-- (1) template 只起到包裹的作用,不会被渲染为任何元素
(2) key 只能绑定给真实的 DOM 元素,无法绑定给 template 标签
-->
<template v-for="item in menus">
<!-- 1.如果children为空则渲染el-menu-item -->
<el-menu-item
:index="item.indexPath"
:key="item.indexPath"
v-if="!item.children"
><i :class="item.icon"></i>{{ item.title }}</el-menu-item
>
<!-- 2.如果children不为空则渲染el-sunmenu -->
<el-submenu :index="item.indexPath" :key="item.indexPath" v-else>
<!-- 一级标题 -->
<template #title>
<i :class="item.icon"></i>
<span>{{ item.title }}</span>
</template>
<!-- 继续使用v-for渲染children生成多个二级菜单 -->
<el-menu-item
:index="subItem.indexPath"
v-for="subItem in item.children"
:key="subItem.indexPath"
>
<i :class="subItem.icon"></i>{{ subItem.title }}</el-menu-item
>
</el-submenu>
</template>
</el-menu>