Simple sidebar based on Vue3

Sometimes when encountering some requirements, it is necessary to realize that the left sidebar is the parent menu, the top of the right content area is the sub-level menu, and the bottom is the module content corresponding to the sub-level menu.

So, the simple implementation is as follows:

1. First configure the routing address [eg: /src/router/index.ts]

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    redirect: '/xxxxxx'
  },
  {
    path: '/xxxxxx',
    name: '帅龍之龍',
    component: () => import('@/views/XXXXXX/index.vue'),
    children: [
      {
        path: '/xxxxxx/aaaaaa',
        name: '赤龍神帝',
        components: { AAAAAA: () => import('@/views/XXXXXX/AAAAAA/index.vue') },
        children: []
      },
      {
        path: '/xxxxxx/bbbbbb',
        name: '待定栏目',
        components: { BBBBBB: () => import('@/views/XXXXXX/BBBBBB/index.vue') },
        children: [],
      },
    ]
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

2. Then implement the page entry [eg: /src/views/XXXXXX/index.vue]

<template>
  <div class="index-page">
    <div class="index-page-navbar">
      <div class="index-page-navbar-item" :class="activePage == 'AAAAAA' ? 'index-page-navbar-active' : ''" @click="handleNavbarItemClick('AAAAAA')">
        <span>赤龍神帝</span>
      </div>
      <div class="index-page-navbar-item" :class="activePage == 'BBBBBB' ? 'index-page-navbar-active' : ''" @click="handleNavbarItemClick('BBBBBB')">
        <span>待定栏目</span>
      </div>
    </div>

    <div class="index-page-content">
      <router-view name="AAAAAA" v-if="activePage == 'AAAAAA'" />
      <router-view name="BBBBBB" v-if="activePage == 'BBBBBB'" />
    </div>
  </div>
</template>
 
<script>
export default {
  data () {
    return {
      // 当前激活的页面
      activePage: '',
    }
  },
  watch: {
 
  },
  created() {
    this.init()
  },
  mounted() {
    // 设置页面标题
    document.title = '帅龍之龍'
  },
  methods: {
    /**
     * 获取初始化参数
     */
    async init() {
      this.activePage = 'AAAAAA'
      const query = this.$route.query
      this.handleMatchRouter(this.activePage)
    },

    /**
     * 激活页面句柄
     */
    handleActivePageChange(activePage) {
      // 点击 el-tab 页面时,将 this.$route.query 置为 {}
      this.$route.query = {}
      this.handleMatchRouter(activePage)
    },

    /**
     * 激活页面句柄
     */
    handleMatchRouter(activePage) {
      const path = this.$route.path
      const b = path.toLowerCase().includes(activePage.toLowerCase())

      if (activePage == 'AAAAAA') {
        if (!b) {
          this.$router.push({
            path: '/xxxxxx/aaaaaa',
            query: this.$route.query,
          }) 
        }
      } else if (activePage == 'BBBBBB') {
        if (!b) {
          this.$router.push({
            path: '/xxxxxx/bbbbbb',
            query: this.$route.query,
          })
        }
      }
    },

    /**
     * 点击侧边导航栏
     */
    handleNavbarItemClick(item) {
      this.activePage = item
      this.$route.query = {}
      this.handleMatchRouter(item)
    },
  }
}
</script>
 
<style lang="less" scoped>
  .index-page {
    display: flex;
    flex-direction: row;
    width: 100%;
    height: 100%;
    position: relative;
    background-color: #fff;

    .index-page-navbar {
      flex: none;
      width: 40px;
      height: 100%;
      border-right: 1px solid #dfe1e6;

      .index-page-navbar-item {
        display: grid;
        width: 100%;
        height: 150px;
        background-color: #fff;
        border-bottom: 1px solid #dfe1e6;
        writing-mode: tb-rl;
        text-align: center;
        align-items: center;
        user-select: none;
        cursor: pointer;
        transition: all ease 0.3s;

        span {
          color: #303133;
          font-size: 14px;
          letter-spacing: 1.5px;
        }
      }

      .index-page-navbar-active {
        background-color: #5e7ce0;

        span {
          color: #fff;
        }
      }
    }
 
    .index-page-content {
      flex: 1;
      position: relative;
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }
  }
</style>

3. Then implement AAAAAA and BBBBBB pages
[such as: /src/views/XXXXXX/AAAAAA/index.vue /src/views/XXXXXX/BBBBBB/index.vue]

<template>
  <div style="width: 100%; height: 100%; display: grid; align-items: center; text-align: center">
    <span style="color: #303133; font-size: 14px;">HelloWorld!...</span>
  </div>
</template>

4. The effect is as follows:~

 

Guess you like

Origin blog.csdn.net/Cai181191/article/details/131614622