vue-router学习

认识路由

  • 路由
    • 路由(routing)就是通过互联网的网络把信息从源地址传输到目的地址的活动
    • 路由器提供了两种机制:路由和转送
      • 路由是决定数据包从来源到目的地的路径
      • 转送将输入端的数据转移到合适的输出端
    • 路由中有一个非常重要的概念叫路由表
      • 路由表本质上就是一个映射表,决定了数据包的指向
  • 后端路由阶段
    • 早期的网站开发整个HTML页面是由服务器来渲染的
      • 服务器直接生成渲染好对应的HTML页面,返回给客户端进行展示
      • 当页面中需要请求不同的路径内容时,交给服务器来进行处理,服务器渲染好整个页面,并将页面返回给客户端
      • 这种情况下渲染好的页面,不需要单独加载任何的js和css,可以直接交给浏览器展示,这样也有利于SEO的优化
  • 前后端分离阶段:
    • 随着Ajax的出现,有了前后端分离的开发模式
    • 后端只提供API来返回数据,前端通过Ajax获取数据,并且可以通过JS将数据渲染到页面中
    • 这样做最大的优点就是前端责任的清晰,后端专注于数据上,前端专注于交互和可视化上
    • 并且当移动端出现后,后端不需要进行任何处理,依然使用之前的一套API即可
    • 目前很多的网站依然采用这种模式开发
  • 单页面富应用阶段:
    • 其实SPA最主要的特点就是在前后端分离的基础上加了一层前端路由
    • 也就是前端来维护一套路由规则
  • 前端路由的核心是什么呢?
    • 改变URL,但是页面不进行整体的刷新
    • 如何实现呢?
      1. URL的hash
        • URL的hash也就是锚点(#),本质上是改变window.location的href属性
        • 我们可以通过直接赋值location.hash来改变href,但是页面不发生刷新
      2. history的方法:
        • history.pushState({}, '', '')
        • history.back()
        • history.forward()
        • history.replaceState({},'','')
        • history.go()

vue-router基本使用

认识vue-router

  • 目前前端流行的三大框架,都有自己的路由实现:
    • Angular的ngRouter
    • React的ReactRouter
    • Vue的vue-router
  • vue-router
    • vue-router是Vue.js官方的路由插件,他和vue.js是深度集成的,适合用于构建单页面应用

安装和使用vue-router

npm安装:

  • 步骤一:安装vue-router

    npm install vue-router --save

    或者脚手架安装的时候已经选择好了vue-router

  • 步骤二:在模块化工程中使用他(因为是一个插件,所以可以通过Vue.use()来安装路由功能)

    • 第一步:导入路由对象,并且调用Vue.use(VueRouter)
    • 第二步:创建路由实例,并且传入路由映射配置
    • 第三步:在Vue实例中挂载创建的路由实例

目录结构

image-20210818231921200

./router/index.js

// 配置路由相关的信息
import VueRouter from 'vue-router'
import Vue from 'vue'
// 1. 通过Vue.use(VueRouter),安装插件
Vue.use(VueRouter)
// 2. 创建VueRouter对象
const routes = [
// 路由对应.vue的映射
]
const router = new VueRouter({
// 配置路由和组件之间的应用关系
routes
})
// 3. 将router对象传入到Vue实例中
export default router

main.js

import Vue from 'vue'
import App from './App'
import router from './router' // 默认找到./router/index.js
Vue.config.productionTip = false
new Vue({
el: '#app',
router, // 挂载router
render: h => h(App)
})

使用:

  1. 目录结构

    image-20210818234334556

  2. 在组件中创建两个模板

    Home.vue

    <template>
    <div>
    <h2>我是首页</h2>
    <p>我是首页内容,哈哈哈</p>
    </div>
    </template>
    <script>
    export default {
    name: "Home"
    }
    </script>

    About.vue

    <template>
    <div>
    <h2>我是关于</h2>
    <p>我是关于内容,呵呵呵</p>
    </div>
    </template>
    <script>
    export default {
    name: "Home"
    }
    </script>
  3. 在index.js中导入两个模板,并在routes中注册两个模板

    import Home from '../components/Home'
    import About from '../components/About'
    ...
    const routes = [
    {
    path: '',
    //重定向到首页
    redirect: '/home'
    },
    {
    path: '/home',
    component: Home
    },
    {
    path: '/about',
    component: About
    }
    ]
  4. 在App.vue中通过标签router-link和router-view使用路由触发页面切换

    <template>
    <div id="app">
    <router-link to="/home">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-view></router-view>
    </div>
    </template>
    <script>
    export default {
    name: 'App'
    }
    </script>
  5. 设置为HTML5的history模式

    //只需在index.js中定义router时,加一个mode
    const router = new VueRouter({
    // 配置路由和组件之间的应用关系
    routes,
    mode: 'history'
    })

router-link的补充

  • to属性:指定跳转的路径
  • tag属性:可以指定router-link之后渲染成什么组件,比如上面的代码会被渲染成一个li元素,而不是a
  • replace属性:禁止返回
  • active-class:router-link对应的路由匹配成功时,增加的class,在进行高亮显示的导航菜单或者底部tabbar时,会使用到该类,可以在index.js中定义router时,指定linkActiveClass为新的class

手动跳转路由:

  • router-link在所有组件中都定义了一个$router属性,实际上就是new VueRouter
<template>
<div id="app">
<router-link tag="button" to="/home">首页</router-link>
<!-- <router-link tag="button" to="/about">关于</router-link>-->
<button @click="aboutClick">关于</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
methods: {
aboutClick() {
this.$router.push("/about")
}
}
}
</script>

动态路由:

  • 某些情况下,一个页面的path路径可能是不确定的,比如我们进入用户界面是,希望是如下的路径:
    • /user/aaa或/user/bbb
    • 除了有前面的/user之外,后面还跟上了用户的Id
    • 这种path和Component的匹配关系,我们称之为动态路由(也是路由和传递数据的一种方式)
  1. 只需在index.js中配置routes时,在path后拼接:

    {
    path: '/user/:userName',
    component: User
    }
  2. 在App.vue引用时通过动态绑定的方式传递给route

    <template>
    <div id="app">
    <router-link tag="button" to="/home">首页</router-link>
    <router-link tag="button" :to="'/user/' + userName">我的</router-link>
    <router-link tag="button" to="/about">关于</router-link>
    <router-view></router-view>
    </div>
    </template>
    <script>
    export default {
    name: 'App',
    data() {
    return {
    userName : 'Elian'
    }
    }
    }
    </script>
  3. 在User.vue中,使用userName

    <template>
    <div>
    <h2>我是用户{{ userName }}界面</h2>
    <p>我是用户的相关信息,嘿嘿嘿</p>
    </div>
    </template>
    <script>
    export default {
    name: "User",
    computed: {
    userName() {
    return this.$route.params.userName
    }
    }
    }
    </script>

认识路由的懒加载(用到时再加载)

  • 官方给出了解释:
    • 当打包构建应用时,Javascript包会变得非常大,影响页面加载
    • 如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了

默认打包方式

image-20210821003047960

  • 官方的意思:
    • 首先,我们知道路由中通常会定义很多不同的页面
    • 这个页面一般情况下,打包后都放在app.*.js中,这么多页面放在一个js文件中,数据非常的大
    • 用户在首次请求的时候一次性在服务器下载这个页面,可能需要花费一定的时间,甚至用户的电脑上还出现了短暂空白的情况
    • 避免这种情况就要使用到懒加载了
  • 路由懒加载做了什么?
    • 路由懒加载的主要作用就是将路由对应的组件打包成一个个的js代码块
    • 只有在这个路由被访问到的时候,才加载对应的组件

image-20210821004233727

  • 路由懒加载的三种方式

    • 方式一:结合Vue的异步组件和webpack的代码分析(老项目中可能用到,但不推荐)

      const Home = resolve => { require.ensure(['../components/Home.vue'], () => {
      resolve(require('../components/Home.vue')) })};
    • 方式二:AMD写法

      const About = resolve => require(['../components/About.vue'], resolve);
    • 方式三:在ES6中,我们可以有更加简单的写法来组织Vue异步组件和Webpack的代码分割

      const User = () => import('../components/User.vue')

vue-router嵌套路由

认识嵌套路由

  • 嵌套路由是一个很常见的功能

    • 比如在home页面中,我们希望通过/home/news和/home/message访问一些内容
    • 一个路径映射一个组件,访问这两个路径也会分别渲染两个组件
  • 路径和组件的关系如下:

    image-20210821011314307

  • 实现路由嵌套有两个步骤:

    • 创建对应的子组件,并在路由映射中配置对应的子路由
    • 在Home组件内部使用router-link router-view标签

    Home.vue

    <template>
    <div>
    <h2>我是首页</h2>
    <p>我是首页内容,哈哈哈</p>
    <router-link tag="a" to="/home/news">新闻</router-link>
    <router-link tag="a" to="/home/message">信息</router-link>
    <router-view></router-view>
    </div>
    </template>
    <script>
    export default {
    name: "Home"
    }
    </script>

    index.js

    {
    path: '/home',
    component: Home,
    children: [
    {
    path: '',
    redirect: '/home/news'
    },
    {
    path: 'news',
    component: HomeNews
    },
    {
    path: 'message',
    component: HomeMessage
    }
    ]
    },

vue-router参数传递

  • 为了演示传递参数,这里再创建一个组件,并且将其配置好,还是分为三步
    • 第一步:创建新的组件Profile.vue
    • 第二步:配置路由映射
    • 第三步:添加跳转的router-link router-view

传递参数的方式

  • 传递参数有两种方式:params和query

    • params的类型(动态路由的方式):

      • 配置路由格式:/router/:id
      • 传递的方式:在path后面跟上对应的值
      • 传递后形成的路径:/router/***
      • 用$route.params.***接收值
    • query的类型:

      • 配置路由格式:/router,也就是普通配置
      • 传递的方式:对象中使用query的key作为传递方式
      • 传递后形成的路径:/router?id=123
      • 用$route.query.***接收值

      image-20210821202424682

  • $route和$router的区别

    • $router是整个VueRouter实例,想要导航到不同URL,则使用$router.push方法
    • $route是处于活跃状态的路由,可以获取name、path、query、params等
  • 所有组件都继承自Vue原型,如果在mian.js中通过Vue.prototype.test = function(){}定义一个方法,那么所有组件中都可以使用这个方法

    main.js

    image-20210821205629456

vue-router导航守卫

为什么使用导航守卫?

  • 我们来考虑一个需求,在一个SPA应用中,如何改变网页的标题呢?

    • 网页标题是通过title来显示的,但是SPA只有一个固定的HTML,切换不同的页面时,标题并不会改变
    • 但是我们可以通过JavaScript来修改title的内容,window.document.title='新的标题'
    • 那么在Vue项目中,在哪里修改,什么时候修改比较合适呢?
  • 两种方式:

    • 可以使用Vue的钩子函数比如created
    • 使用导航守卫
      • 在每个route中,添加meta属性,它是一个对象
      • 调用router.beforeEach(to, from, next)(前置守卫)方法或router.afterEach(to, from)

    image-20210821212246118

  • 导航守卫补充:

    • 补充一:如果是后置钩子,也就是afterEach,不需要主动调用next()函数

    • 补充二:上面我们使用的导航守卫,被称之为全局首位

    • 补充三:

      • 路由独享的守卫
      • 组件内的守卫

      路由独享的守卫

keep-alive

  • keep-alive也是Vue内置的一个组件,可以使被包含的组件保留原状态,或避免重新渲染

  • router-view也是(VueRouter下的)一个组件,如果直接背包在keep-alive里面,所有路径匹配到的视图组件都会被缓存

理解为什么使用keep-alive

  • 从vue生命周期可知,每次页面切换时,组件都会被创建、销毁,所以嵌套路由的时候,都会到最初我们配置的默认的路由上,无法到我们最后点击的子路由上

使用keep-alive实现demo

  • Demo使用方法(当点击了首页时,默认指定news,点击message,点击其他菜单,再点击首页回到message):

    • 取消route下home中的默认跳转
    • 在App.vue中router-view的外层套上keep-alive标签
    • 另外使用activated()钩子和beforeRouteLeave()组件内导航守卫
    <template>
    <div>
    <h2>我是首页</h2>
    <p>我是首页内容,哈哈哈</p>
    <router-link tag="a" to="/home/news">新闻</router-link>
    <router-link tag="a" to="/home/message">信息</router-link>
    <router-view></router-view>
    </div>
    </template>
    <script>
    export default {
    name: "Home",
    data() {
    return {
    path: '/home/news'
    }
    },
    activated() {
    this.$router.push(this.path)
    },
    deactivated() {
    },
    beforeRouteLeave( to, from, next ) {
    console.log(this.$route.path);
    this.path = this.$route.path
    next()
    }
    }
    </script>

    注意:只有在keep-alive的情况下,才能使用activated和deactivated方法

  • 但是这个时候的keep-alive包裹了所有App下的子组件,都会被缓存,这时只要在keep-alive中添加属性:

    <keep-alive include="Home">
    <router-view/>
    </keep-alive>

    这里Home指的是Home.vue,export时指定的name

posted @   coderElian  阅读(40)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示