[重构倒数第23天] - Tab 的 page 加入 router

前言

该系列是为了让看过Vue官方文件或学过Vue但是却不知道怎麽下手去重构现在有的网站而去规画的系列文章,在这边整理了许多我自己使用Vue重构很多网站的经验分享给读者们。

我们在开发专案的时候不是所有的专案都是采用前後端分离的方式来进行开发,有许多专案是建立在後端框架内,然後去撰写前端 view 的部分,像是 Laravel 或是 Django 等等,这类的web後端框架不只是 render,连 router 也是在後端定义的,所以基本上前端这边开发上面就是写单纯的 html、css 还有 javascript,但是当你开始接手这类型的专案的时候,多少都会希望采用现在比较流行的开发方式去开发前端,所以我们会在後端的框架内载入Vue改写以前单纯用 html、css 还有 javascript 写的页面,不过当我们今天在使用 Vue 开发的时候,我们就可以在一些只有前端处理的页面,透过 vue-router 来自定义前端的 router ,这样我们就不需要再透过後端定义的方式来处理网址的部分。

vue-router 基本使用方式

我们可以使用 vue-router 来帮我们达成透过 client side render 的效果,也可以透过前端的方式来自定义 router ,这也是我们所谓的 SPA ( single-page application ),我们来快速的看一下如何使用 vue-router。

首先我们应该先来载入vue-router,我们先假设我们接手的专案是很传统的MVC架构,不是透过 Vue-cli 或是其他自动化工具整合过的专案,所以无法透过 npm 的方式来进行安装,所以我们可以透过CDN的方式来引入。

注意!!! 这边我们要载入的 vue-router 版本要是 v4.x 的版本, v4.x 以上的版本才可以给 Vue3 去做使用。

我们来看一下 vue-router 载入後的设定

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

const router = createRouter({
  history: createWebHistory(),
});

createApp(App).use(router).mount("#app");

首先我们从 Global 中的 VueRouter 取出createRoutercreateWebHashHistory 这两个函式,在这边我列出三个非常重要的 API 特别来介绍

  • createRouter:创建一个可以被 Vue 使用的 Router 实体。

  • createWebHistory:可以创建一个 HTML5 的 Web History 切换页面 ( 需要有http的协议提供服务 ) 。

  • createWebHashHistory:可以创建 hash History 来切换页面 ( 可以使用在没有 server 的 web上面,或是当 server 不能处理任意router 的时候,可以使用,只是网址後面会带入 # )。

    例 : https://www.demo.com/#/about

再来我们要新增 router 的内容

// component A
const Home = { template: "<div>Home</div>" };

// component B
const About = { template: "<div>About</div>" };

// 定义 router 的内容
const routes = [
  { path: "/", component: Home },
  { path: "/about", component: About }
];

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

我在上面定义了两个 component,这两个 component 就是我要切换的页面,然後塞入 createRouter实体内,这样一来我们 Vue 就具备了这两个 component 以及router的资讯,接下来我们要把页面的内容给 render 到页面上面。

<div id="app">
  <nav>
    <router-link to="/">Go to Home</router-link>
    <router-link to="/about">Go to About</router-link>
  </nav>
  <router-view></router-view>
</div>
  • router-view:当挂载 vue-router 後,可以直接使用 <router-view>这个组件来 render页面的内容。

  • router-link:可以透过<router-link to="/about">的指定方式,来切换页面,预设 router-link 会编译成 <a>,我们也可以透过它的 API 来改编译後的html tag。

这样子我们就可以在传统的专案上面使用框架的方式来开发还有定义 router,只不过这要特别注意,vue-router是属於 client side render 的方式,也就是说它的页面都是透过 javascript 的方式给 render 出来,自然SEO的效果就差了点,所以如果你是要着重在SEO的网站上面,尽量不要把重点的SEO页面用 vue-router 的方式实作。

然後我们需要做一点的防呆处理

const routes = [
  { path: "/", component: Home },
  { path: "/about", component: About },
  { path: "/*", redirect: "/"}
];

我们在 routes 的最後新增一个 /*以防止一般 user 随便输入,所以当今天 user 随便输入网址的时候,如果跟 routes 里面没有一个 path 符合的话,就会比对到最後的 /*这个度部分,去执行 redirect 转址到 /这个路径下。

注意! { path: "/*", redirect: "/"} 一定要放在最後,如果放在前面的话,它後面的 routes 就不会被比对,而是会直接 redirect,这点一定要特别的注意,关於 vue-router 的更多使用方式可以再参考官网 https://next.router.vuejs.org/guide/#javascript。

实际用用看

我们来看一下一般分页里面有出现tab的区块的时候,应该怎麽做

Vue Router

嵌套路由 (Nested Routes)

首先我们会需要定义一下/about 底下的 router,这边我们使用嵌套路由 (Nested Routes) ,我们先到 main.js

import { createApp } from "vue";
import { createRouter, createWebHistory } from "vue-router";
import App from "./App.vue";
import Home from "./view/Home.vue";
import About from "./view/About.vue";
import Html from "./components/about/html.vue";
import Css from "./components/about/css.vue";
import Js from "./components/about/js.vue";

const routes = [
  { path: "/", component: Home },
  {
    path: "/about",
    component: About,
    children: [
      {
        path: "",
        component: Html
      },
      {
        path: "css",
        component: Css
      },
      {
        path: "js",
        component: Js
      }
    ]
  },
  { path: "/*", redirect: "/" }
];

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

createApp(App).use(router).mount("#app");

Nested Routes 文件 :https://router.vuejs.org/guide/essentials/nested-routes.html#nested-routes

这边的 children 就是让我们去设定再 /about 之後的 router。

所以我们在 App.vue 的地方有放置 <router-view></router-view> ,去渲染不同的页面,但是现在再 about 里面也需要放 <router-view></router-view> ,去渲染 /about 後面的不同的页面

about.vue

<template>
  <h1>about</h1>
  <div class="tab_box">
    <nav>
      <router-link to="/about/">html</router-link>
      <router-link to="/about/css">css</router-link>
      <router-link to="/about/js">js</router-link>
    </nav>
    <div class="content">
      <router-view></router-view>
    </div>
  </div>
</template>

这样一来主根目录下面的去读取 App.vue 下面的 router-view,然後 /about 底下的就是 About.vue 下面的 router-view去 Render,非常的简单就可以做出这种嵌套路由的网页。

关於选取状态的样式!

我们在点击 router-link 的时候,通常会要让那个按钮的状态显示被标记,所以我们会需要设定一个状态的 class,但是其实 router-link 本身就有提供 active状态的 class 去对应网址的部分,我们只需要填上css,就可以了达到 active状态的呈现。

mike vue3 router

.router-link-exact-active 这个 class 就会是对应你的 router ,然後加入上去,所以我们就在这个样式上面加一下

> a {
  &.router-link-exact-active {
    color: #fff;
    background-color: #498ba7;
  }
}

这样就可以读取到了,你会发现怎麽有两个 active class。

  • router-link-active : 目前 router 符合 /about 就会出现,後面 /about/css 这样也会出现。

  • router-link-exact-active : router 要完全符合定义好的 router 才会出现。

codesandbox 范例 : https://codesandbox.io/s/vue-nested-routes-zde77

先告一个段落

其实 vue-router 看官网就大概知道如何使用,但今天重点着重在 web重构上面的使用情境,我们应该要多多考虑使用者在实际的使用上面会有那些问题,而不是只把效果做出来就好。

QRcode

那如果对於Vue3不够熟的话呢?

Ps. 购买的时候请登入或注册该平台的会员,然後再使用下面连结进入网站点击「立即购课」,这样才可以让我获得更多的课程分润,还可以帮助我完成更多丰富的内容给各位。

我有开设了一堂专门针对Vue3从零开始教学的课程,如果你觉得不错的话,可以购买我课程来学习
https://hiskio.com/bundles/9WwPNYRpz?s=tc

那如果对於JS基础不熟的朋友,我也有开设JS的入门课程,可以参考这个课程
https://hiskio.com/bundles/b9Rovqy7z?s=tc

订阅Mike的频道享受精彩的教学与分享

Mike 的 Youtube 频道
Mike的medium
MIke 的官方 line 帐号,好友搜寻 @mike_cheng


<<:  Day 3: 我不想知道的太多,以免被连累.单一职责与最小知道原则

>>:  【Day 8】Python JSON与demjson

[Day 21] 资料产品与 DataOps 原则

今天来细看 DataOps 的原则,尽量会搭配过去实作的经验一起做说明。 1. 持续地满足客户需求 ...

Day03 - Amazon ECS Anywhere 基础说明与建置(上)

这系列主要就是讲Amazon ECS Anywhere 所以先来看看阳春版怎麽建立出来 基础运行元件...

[Day 15] 资料产品生命周期管理-预测模型

尽管都是模型,但预测模型目的在於预测未来,所以开发方式也会和描述型模型有所差异。 Initiatio...

Day 14 : 程序码日志与品质

今天来探讨怎麽留下程序码纪录和提升自己的程序码品质。(终於快写到一半了XDDD) 程序码日志 程序设...

GKE (二)

GKE 应用 经过昨天说的建立GKE想必应该已经有了自己的丛集了,那如何在GCP上去使用GKE呢?可...