C#使用web搭建界面-Vue3本地导航

        自己在使用C#搭建的界面是单页应用,所以需要使用vue中的vue-route做局部刷新,于是尝试element-plus结合route-view完成导航栏的搭建。在使用vue-route过程中自己一直没弄明白route-view是怎么将局部页面映射到对应的视图中,只是在menu中加router-view以及routes路由中有children时也需要加一层view就会正确的展示,后续弄懂原理再回来做补充。

配置路由

        主要是添加自定义的菜单ICON,去掉App.vue中的首页导航

import type { RouteRecordRaw } from 'vue-router'

/**
 * 路由配置
 * @description 所有路由都在这里集中管理
 */
const routes: RouteRecordRaw[] = [
  {
    path: '/local',
    name: 'home',
    component: () =>
      import(/* webpackChunkName: "home" */ '@cp/TransferStation.vue'),
    meta: {
      title: 'Home',
      iconName: 'HomeFilled',
    },
    children: [
      {
        path: 'config',
        name: '全局配置',
        component: () =>
          import(/* webpackChunkName: "bar" */ '@views/local/config.vue'),
        meta: {
          title: '全局配置',
          iconName: 'Setting',
        },
      },
      {
        path: 'debug',
        name: '调试',
        component: () =>
          import(/* webpackChunkName: "bar" */ '@views/local/debug.vue'),
        meta: {
          title: '调试',
          iconName: 'Orange',
        },
      },
    ],
  },
  /**
   * 子路由示例
   */
  {
    path: '/foo',
    name: 'foo',
    component: () =>
      import(/* webpackChunkName: "foo" */ '@cp/TransferStation.vue'),
    meta: {
      title: 'Foo',
      iconName: 'Shop',
    },
    redirect: {
      name: 'bar',
    },
    children: [
      {
        path: 'bar',
        name: 'bar',
        component: () =>
          import(/* webpackChunkName: "bar" */ '@views/foo/bar.vue'),
        meta: {
          title: 'Bar',
          iconName: 'Ship',
        },
      },
    ],
  },
]

export default routes

修改App.vue

        在挂载时绑定C#调用js时的全局函数,直接挂载home.vue做导航

<template>
  <HomeEntry></HomeEntry>
</template>

<script setup lang="ts">
import { computed, onMounted, onBeforeUnmount, onUpdated } from 'vue'
import router from '@/router'
import { getRoutePathByName } from '@/router/RouteUtil'
import { registerJiaJs, unRegisterJiaJs } from '@/plugins/local/jiaCb'
import { LoadGlobalConf } from '@/stores/local/config'
import HomeEntry from '@views/home.vue'

function onGetConfPage(page: string): void {
  let path = getRoutePathByName(page)
  console.log('load_first_page page=' + page + ';path=' + path)
  router.push(path)
}
onMounted(() => {
  registerJiaJs()
  LoadGlobalConf(onGetConfPage)
})
onBeforeUnmount(() => {
  unRegisterJiaJs()
})
</script>

 首页导航的布局

首页主要是分头部,侧边栏以及右侧每个页面展示的区域,以下是相关的实现

Header.vue

<template>
  <el-row align="middle">
    <el-col :span="1" @click="onClikCollapse">
      <el-icon v-if="!isCollapse" :size="30" color="hotpink"><Fold /></el-icon>
      <el-icon v-else :size="30" color="hotpink"><Expand /></el-icon
    ></el-col>
    <el-col :span="4"
      ><p><strong>云浮翼明</strong></p></el-col
    ><el-col :span="1" :offset="18"
      ><el-avatar :size="50" :src="avatar" /></el-col
  ></el-row>
</template>
<script setup>
import { toRefs } from 'vue'
import avatar from '@img/avatar.jpg'
const props = defineProps({ isCollapse: Boolean })
const emits = defineEmits(['onClikCollapse'])
const { isCollapse } = toRefs(props)

function onClikCollapse() {
  emits('onClikCollapse')
}
</script>

<style scoped>
.el-row {
  height: 70px;
  flex-wrap: wrap;
  flex-direction: row;
}
</style>

侧边栏在实现上需要注意el-menu-item中子路径的index拼接问题

<template>
  <el-menu
    :default-active="$route.path"
    class="left-sidebar"
    :collapse="isCollapse"
    router
    unique-opened
    @open="handleOpen"
    @close="handleClose"
  >
    <!-- 遍历菜单 -->
    <template v-for="item in routes">
      <!-- 含有子菜单 -->
      <template v-if="item.children">
        <!-- 第一层 含有子菜单菜单 -->
        <el-sub-menu :index="item.path" :key="item.path">
          <template #title>
            <el-icon>
              <component :is="item.meta.iconName" />
            </el-icon>
            <span>{{ item.meta.title }}</span>
          </template>

          <!-- 第二层 子菜单遍历 -->
          <el-menu-item
            v-for="subItem in item.children"
            :key="subItem.path"
            :index="item.path + '/' + subItem.path"
          >
            <el-icon>
              <component :is="subItem.meta.iconName" />
            </el-icon>
            <template #title>
              <span>{{ subItem.meta.title }}</span>
            </template>
          </el-menu-item>
        </el-sub-menu>
      </template>

      <!-- 第一层 不含子菜单  -->
      <template v-else>
        <el-menu-item :index="item.path" :key="item.path">
          <el-icon>
            <component :is="item.meta.iconName" />
          </el-icon>
          <template #title>
            <span>{{ item.meta.title }}</span>
          </template>
        </el-menu-item>
      </template>
    </template>
  </el-menu>
</template>

<script setup>
import { computed, ref, toRefs } from 'vue'
import { useRoute } from 'vue-router'
import routes from '@/router/routes'
const props = defineProps({ isCollapse: Boolean })
const { isCollapse } = toRefs(props)
const route = useRoute()

const handleOpen = (key, keyPath) => {
  console.log(key, keyPath)
}
const handleClose = (key, keyPath) => {
  console.log(key, keyPath)
}
</script>

<style scoped>
.left-sidebar:not(.el-menu--collapse) {
  width: auto;
  min-height: 400px;
}
</style>

最后整合到home.vue中

<template>
  <div id="main">
    <Header :isCollapse="isCollapse" @onClikCollapse="onClikCollapse"></Header>
    <el-row>
      <el-col :span="isCollapse ? 1 : 3">
        <SideBar :isCollapse="isCollapse"></SideBar>
      </el-col>
      <el-col :span="isCollapse ? 23 : 21">
        <router-view></router-view>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import Header from '@cp/Header.vue'
import SideBar from '@cp/SideBar.vue'

const isCollapse = ref(true)
function onClikCollapse() {
  isCollapse.value = !isCollapse.value
}
</script>
<style lang="less" scoped>
#main {
  width: 100%;
  height: 100%;
}
</style>

下面展示效果

展示导航

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值