Vue大事件练习(保姆级教程)04

161 阅读1分钟

06-首页(渲染左侧菜单栏)

1656356098534.png

1.1-发送ajax请求左侧菜单栏

1656353256191.png

1656353353038.png

  • 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
       }
     },
    
  • 左侧菜单栏 + 右侧个人信息

1656353869952.png

1656353909331.png

1.3-渲染左侧菜单栏

  • 难点分析

    • (1)如果el-menu没有二级菜单就是el-menu-item
    • (2)如果el-menu有二级菜单就是el-submenu
    • (3)服务器返回的数组, 有一个children属性。 如果这个属性为空,就代表没有二级菜单。如果是一个数组就代表有二级菜单。
  • 思路分析

    • (1)也就说,这个数组在使用v-for指令的时候。无法确定到底要生成哪一个标签。需要根据数组的元素来判断。
    • (2)解决方案:使用template标签包裹,根据条件来判断到底要渲染哪一个元素
  • 举一反三:只要v-for指令渲染的标签是不固定的,就可以使用template标签进行包裹后渲染

1656354632296.png

  • 核心结构如下

    • <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')
          }
      }
      

1656355820621.png

  • 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>