【vue3+vite应用从0到1】2.增加通用页面及组件

354 阅读3分钟

简介:路由及守卫,子路由,环境变量,manualChunks代码拆分

因为在移动端开发SPA时候,我们大多数都会遇到这种需求,下方为导航菜单,切换打开不同页面。并且通过不同链接进入时导航高亮也要正确显示,还有一些通用页面,如404,首页,认证页。这个文档在第一篇文章的基础上来完成这个需求。

目标

切换底部导航栏能够切换页面,在这基础上对一些模块进行优化和配置

【STEP1】新建页面

如果达到我们的目标我们需要建如下几个页面及组件,其中components/FooterNav.vue 是底部导航,views/layout.vue是内页的承载页,通过子路由嵌入home,message,me三个页面。

其中layout.vue 和 App.vue代码差不多,但是他引入了FooterNav组件,并增加了子路由插槽

<template>
  <div class="layout-container">
    <div class="layout-main">
      <router-view v-slot="{ Component, route }">
          <keep-alive v-if="route.meta.isKeepAlive">
            <component :is="Component" />
          </keep-alive>
          <component v-else :is="Component" />
      </router-view>
    </div>
    <FooterNav class="layout-footer"></FooterNav>
  </div>
</template>
<script setup lang="ts">
import FooterNav from "@/components/FooterNav.vue";
</script>
<style lang="less" scoped>
.layout-container {
}
</style>

【STEP2】配置路由

在这一步将配置路由,并使用守卫来修改当前App的title

import { createWebHistory, createRouter, RouteRecordRaw } from "vue-router";

// 只有懒加载没有魔法注释咯
const WelcomeView = () => import("@/views/welcome.vue"); 
const LayoutView = () => import("@/views/layout.vue");
const NotFoundView = () => import("@/views/notfound.vue");
const HomeView = () => import("@/views/home.vue");
const MeView = () => import("@/views/me.vue");
const MessageView = () => import("@/views/message.vue");

const routes: RouteRecordRaw[] = [
  { path: "/", component: WelcomeView },
  // 配置404
  {
    path: "/:pathMatch(.*)*",
    name: "NotFound",
    component: NotFoundView,
    meta: {
      isKeepAlive: true,
    },
  },
  // layout承接子路由
  {
    path: "/layout",
    redirect: "/home",
    component: LayoutView,
    meta: {
      title: "首页",
      isKeepAlive: true,
    },
    children: [
      {
        path: "/home",
        component: HomeView,
        meta: {
          title: "首页",
          isKeepAlive: true,
        },
      },
      {
        path: "/me",
        component: MeView,
        meta: {
          title: "我的",
          isKeepAlive: true,
        },
      },
      {
        path: "/message",
        component: MessageView,
        meta: {
          title: "消息",
          isKeepAlive: true,
        },
      },
    ],
  },
];

const router = createRouter({
  history: createWebHistory(), // 路由使用的webHistory模式
  routes,
});

// 导航守卫
// 通过读取路由的meta.title 修改 document.title
router.beforeEach((to, from) => {
  const { title } = to.meta;
  document.title = title || import.meta.env.VITE_APP_TITLE; // 如果title不存在则读取VITE配置
  return true;
});
export default router;

【STEP3】底部导航组件

听劝,前端的图片告别.png用.svg吧的示例就是用导航组件

【STEP4】一些配置

4.1 vite的环境变量

应用的默认标题就是在环境变量中配置,官方文档 import.meta.env.VITE_APP_TITLE

4.2 代码分隔

在webpack是这样做的

我们以前使用vue2+webpack时为了按照自己需求进行拆分打包,会使魔法注释进行按需打包,如

import(/* webpackChunkName: "index" */ @/views/index.vue)

在vite你需要这样做

ps:vite的打包是用rollup

但是在vite就不能直接像webpack一样用魔法注释咯, 有一些封装好了的代码分隔的npm组件你可以直接用,如vite-plugin-chunk-split

或者你可以参考下方示例进行自定义配置 你可能需要使用 vite.config.js 中配置build.rollupOptions

下面是一个简单的例子:

import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          // 假设你有两个页面模块 pageA 和 pageB
          if (id.includes('/path/to/pageA') || id.includes('/path/to/pageB')) {
            // 将 pageA 和 pageB 打包到同一个chunk
            return 'pageAB';
          }
          // 其他库或模块可以继续进行默认的代码分割,或你可以增加更多的规则。
          // 如果没有返回值,则会按照 Rollup 的默认行为处理模块。
        },
      },
    },
  },
});

系列文章