前面我们讲过使用 vue-cli 创建的项目本质上讲是一个 SPA(单页面)项目,而不同页面之间的切换,就需要通过 前端路由 来实现。

# 页面切换:

  没有学习 vue 之前,在单个页面中实现页面切换的话,通常采用 display 进行显示和隐藏

代码实现

不想写 css 的话,可以直接引入 bootstrap.css😂

  在没有学习 vue-Router 之前,我们可以使用动态组件达到同样的效果。

代码实现

组件切换案例 (opens new window)(动态路由版)

  那后面我们要使用的Vue Router (opens new window) ,是基于什么原理实现的那?

# 一、路由管理

  下面我们可以使用锚链接来模拟一些 vue-router 是实现

提示

  vue-router 默认 hash 模式,如果为了美观可以将其修改为 history 模式。

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

  但是这样,会导致一些额外的配置 (opens new window)

# 1、锚链接

特点:

  地址栏上有浏览历史(location.hreflocation.hash

原理:

利用 ·<a>标签的 href 内容和 id 属性的关联性。

提示

  要额外注意 router 盒子的位置 —— 在页面展示之前。

代码 ✍ 实现:

锚链接与全屏滚动 (opens new window)

<body>
  <!-- 切换控制(key) -->
  <div class="router">
    <a href="#Home">首页</a>
    <a href="#Cart">购物车</a>
    <a href="#Search">搜索</a>
  </div>

  <!-- 页面(value) -->
  <div id="Home">home-page<div>
  <div id="Cart"><div>
  <div id="Search"><div>
</body>

# 2、路由分析

记忆

  多个路由 route 可以由一个路由器 router 控制。

  上面是利用锚链接与 id 盒子的对应关系,实现了跳转。

  这种实现模式,我们同样可以应用在Hash 地址(锚链接)与组件之间的对应关系中。

# 3、实现原理

  参照对应关系,我们可以通过动态组件的方式,按照下面的步骤达到同样的效果。

前端路由实现
<template>
  <div>
    <div class="router">
      <a href="#Home">首页</a>
      <a href="#Cart">购物车</a>
      <a href="#Search">搜索</a>
    </div>

    <hr/>

    <!-- 使用动态组件 -->
    <div class="main">
      <component :is="componentS"></component>
    </div>

  <div>
</template>

<script>
  import Home from '@/components/Home.vue'
  import Cart from '@/components/Cart.vue'
  import Search from '@/components/Search.vue'

  export default {
    data() {
      return {
        componentS: 'Home'
      }
    },
    components: {
      Home,
      Cart,
      Search
    },
    created() {
      // 监听🚩hash值变化
      window.onhashchange = () => {
        switch(location.hash) {
          case '#/home':
            this.comp_Name = 'Home'
            break
          case '#/cart':
            this.comp_Name = 'Cart'
            break
          case '#/search':
            this.comp_Name = 'Search'
            break
        }
      }
    }
  }
</script>
  • 点击页面的路由链接
  • URL 地址栏中的 Hash 值变化
  • 前端路由监听到 Hash 地址变化
  • 将当前 Hash 地址对应的组件渲染到浏览器中

# 二、vue-router

  通过上面的案例,我们发现手动配置编写路由,十分笨拙,此时就可以使用 vue-router (opens new window) 来简化开发。

原生的锚链接的方式实现跳转,就是它们简单对应关系耦合性太高,不方便管理。而 vue-router 通过将它们间的对应关系抽离出来,单独进行管理,从而完美的解决了问题。

# 1、安装使用 ✨

① 安装

npm i vue-router@3

① 构建 router

  • router / index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter) // 插件注册成功(vue中能使用vue-router了)

// 大佬router产生了✍
export default new VueRouter({
  //……
  routes: [
    // 路由规则(对应关系)
    { path: '/home', component: Home },
    { path: '/cart', component: Cart },
    { path: '/search', component: Search }
  ]
})

② 全局使用

main.js

import router from '@/router/index.js'

new Vue({
  router, // router: router的简写
  render: (h) => h(App)
}).$mount('#app')
<template>
  <div>
    <!-- 1、跳转控制区域 -->

    <!-- <div class="router">
      <a href="#Home">首页</a>
      <a href="#Cart">购物车</a>
      <a href="#Search">搜索</a>
    </div> -->

    <router-link to="/home">首页</router-link>
    <router-link to="/cart">购物车</router-link>
    <router-link to="/search">搜索</router-link>

    <hr/>

    <!-- 2、展示区域 -->

    <!-- <div class="main">
      <component :is="componentS"></component>
    </div> -->

    <div class="main">
      <router-view></router-view>
    </div>

  <div>
</template>

观察

  在前面我们使用 vue-router 的时候,我们发现即使我们在路由规则router-link 中都没有加上#/,但地址栏也会自动帮我们生成。

# 2、懒加载

  原先的组件引入方式有一个缺陷就是,不管该组件有没有使用,都得先进行加载。

解决方案:

不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件

代码实现:

// 异步加载
// const Home = () =>
//   Promise.resolve({
//     import('@/components/Home.vue') // 返回 Promise
//   })

// 简化:

const Home = () => import('@/components/Home.vue')

# 三、开发应用

  要说 vue-router 的应用,那后台管理必然有一席之地:

  为了节约时间,我们就直接在原动态组件中的组件切换案例 (opens new window)中进行改造,将其用 vue-router 实现一下。

简单实现

组件切换案例 (opens new window)(vue-router 版)

# 1、重定向

  在上面案例中如果我们不使用重定向,那么页面渲染完时,<router-view>并没有页面显示。

原因:

刚进入 HomeView 组件时,默认的路径为/,而 vue-router 并没有检测到相关路由配置。

解决:

export default new VueRouter({
  routes: [
    {
      path: '/',
      redirect: '/part1' // 重定向✨
    },
    {
      path: '/part1',
      component: () => import('../page/PartOne')
    }
  ]
})

# 2、active-class 属性

官方:

active-class (opens new window)

  还有在上面案例中,我们发现:

<template>
  <li>
    <router-link active-class="active" to="/part1">part1</router-link>
  </li>
  <li>
    <router-link active-class="active" to="/part2">part2</router-link>
  </li>
  <li>
    <router-link active-class="active" to="/part3">part3</router-link>
  </li>
</template>

<style scoped>
  .active {
    display: inline-block;
    background: #efefef;
  }
</style>

# 3、注意事项

思考 1:

常规组件 和 路由组件 该怎么区分?

vue-cli_project
├─ src
│  ├─ components(常规组件)
│  │  └─ HelloWorld.vue
│  ├─ pages(路由组件)
│  │  └─ Home.vue
│  ├─ router
更新于 : 8/7/2024, 2:16:31 PM