Vue路由——route

目录

前言:

单页面应用的优缺点:

单页面应用的优点

单页面应用的缺点:

路由route和路由器router

路由的组成

路由的使用

1、创建组件

2、安装vue-router

3、配置vue-router环境并使用

注意事项:

多级路由

创建二级路由组件

配置二级路由关系

routerLink使用

设置二级路由使用位置

路由配置项:name

第一步:在路由关系中,添加name的配置

路由query传参

第一步:配置好详情页组件

第二步:router/index.js

第三步:传递参数,哪里点击,哪里传递

第四步:拿取数据

路由params传参

第一步:新建好detail组件,并配置好路由关系

第二步:传递参数

第三步:detail组件接收参数

路由的props

router-link的replace属性

编程式路由导航

[(1) push模式:](#(1) push模式:)

[(2) replace模式:](#(2) replace模式:)

[(3) 前进:](#(3) 前进:)

[(4) 后退:](#(4) 后退:)

[(5) 前进或后退几步:](#(5) 前进或后退几步:)

[(6) 使用编程式路由导航的时候,需要注意:](#(6) 使用编程式路由导航的时候,需要注意:)

缓存路由组件

activated和deactivated

常用配置项

[1. path ------ 路由匹配路径](#1. path —— 路由匹配路径)

[2. component ------ 匹配时渲染的组件](#2. component —— 匹配时渲染的组件)

[3. children ------ 嵌套子路由配置](#3. children —— 嵌套子路由配置)

[4. name ------ 路由命名](#4. name —— 路由命名)

[5. redirect ------ 路由重定向](#5. redirect —— 路由重定向)

[6. alias ------ 路径别名](#6. alias —— 路径别名)

[7. props ------ 将路由参数作为组件 props](#7. props —— 将路由参数作为组件 props)

[8. meta ------ 路由元信息](#8. meta —— 路由元信息)


前言:

在web开发中分为传统web应用和单页面web应用。传统web应用是指在页面切换时是对多个HTML页面之间的切换。而单页面web应用是指整个页面只有一个HTML页面,点击只是对当前页面中的组件进行切换,属于页面局部更新

单页面应用的优缺点:

单页面应用的优点

1、提供了更加吸引人的用户体验:具有桌面应用的即时性、网站的可移植性和可访问性。

2、单页应用的内容的改变不需要重新加载整个页面,web应用更具响应性和更令人着迷。

3、单页应用没有页面之间的切换,就不会出现"白屏现象" ,也不会出现假死并有**"闪烁"现象**

4、单页应用相对服务器压力小,服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍。

5、良好的前后端分离。后端不再负责模板渲染、输出页面工作,后端API通用化,即同一套后端程序代码,不用修改就可以用于Web界面、手机、平板等多种客户端

单页面应用的缺点:

1、首次加载耗时比较多。

2、SEO问题,不利于百度,360等搜索引擎收录。

3、容易造成CSS命名冲突。

4、前进、后退、地址栏、书签等,都需要程序进行管理,页面的复杂度很高,需要一定的技能水平和开发成本高。

目前较为流行的是单页面应用的开发。

如果想使用Vue去完成单页面应用的开发,需要借助Vue当中的路由机制。


路由route和路由器router

路由器router是来管理/调度各个路由的

对于一个应用来说一般路由器只有一个,路由有多个

路由的组成

路由也是由键值对组成的

key是路径,value是对应的组件

路由本质:一组路由就是一组对应关系

路由器本质:管理多组对应关系

路由的使用
1、创建组件

使用路由之前我们需要先创建好组件,一般我们在src下面创建views文件夹,然后写路由组件

2、安装vue-router

(1) vue2 要安装 vue-router3

npm i vue-router@3

(2) vu3要安装vue-router4

npm i vue-router@4

3、配置vue-router环境并使用

在main.js中

javascript 复制代码
import Vue from "vue";
import App from "./App.vue";


Vue.config.productionTip = false;
// 导入路由器对象
import router from "./router";

const vm = new Vue({
  render: (h) => h(App),
    // 一旦使用了vue-router插件,那么new Vue的时候就可以直接传递一个配置项
  // 注册路由器对象
  router
}).$mount("#app");
console.log(vm);

接着在src目录下,新建一个router文件夹,新建index.js配置路由器对象并暴露

javascript 复制代码
import VueRouter from "vue-router";
import Vue from 'vue';
Vue.use(VueRouter)

// 导入路由组件
import Home from '@/views/Home';
import NotFound from '@/views/NotFound';
import Detail from '@/views/Detail';

const routes = [
    {
        path: '/',
        redirect: '/home'
    },
    {
        path: '/home',
        component: Home,
        name: 'home',
        // children:[
        //     {}
        // ]
    },
    {
        path: '/detail/:id',
        component: Detail,
        name: 'detail',
        props(route) {
            return {
                id: route.params.id
            }
        }
    },
    {
        path: '*',
        component: NotFound,
        name: 'notfound'
    }
]

// 创建路由器
export const router = new VueRouter({
    routes
})

它们会被路由配置中的component引入,当路由跳转到对应路径时,这些组件会被渲染到

<router-view>中

配置好后去路由组件使用

javascript 复制代码
<template>
    <div>
        <h1>home组件</h1>
        <router-link to="/detail">跳转</router-link>
        <button @click="$router.push(
            '/detail/123'
        )">跳转到详情页</button>
    </div>
</template>
<script>
export default {
    name: 'home',
    activated() {
        console.log('actived');

    },
    deactivated() {
        console.log('deactivated');
    }
}
</script>
<style></style>

然后让路由组件显示

javascript 复制代码
<template>
  <div class="app">
    <!-- 路由占位,标记好路由组件显示得位置 -->
    <KeepAlive>
      <router-view />
    </KeepAlive>
  </div>
</template>

<script>
export default {
  name: 'App',
}
</script>

<style>
</style>

<router-view>是 Vue Router 提供的路由出口。当访问不同 URL 时,匹配到的路由组件会渲染在这里。

<KeepAlive>包裹了<router-view>,作用是缓存被切换掉的路由组件,避免重复创建和销毁,保留组件状态。

注意事项:

1、路由组件一般会和普通组件分开存放,路由组件放到pages或views目录,普通组件放到components目录下。

2、路由组件在进行切换的时候,切掉的组件会被销毁,可用destroyed生命周期钩子证实

3、路由组件的两个属性:route和router

$route:属于自己的路由对象。

$router:多组件共享的路由器对象。


多级路由

多级路由又叫嵌套路由,父路由对应的组件内部自身包含<router-view> ,用于渲染子路由组件,从而形成嵌套的 UI 结构

创建二级路由组件
配置二级路由关系
javascript 复制代码
//....
import Hot from "@/views/home/hot.vue";
import Agree from "@/views/home/agree.vue";
import More from "@/views/home/more.vue";

const router = new VueRouter({
  // 配置路由规则  配置一组组路由关系,
  // 每一组路由关系都是一个对象:
  // key:路径==>path
  // value:组件==>component
  // 第一步:配置好路由关系:key--value
  routes: [
    {
      path: '/home',//注意要以/开头
      component: Home,
      // children配置项,配置二级路由
      children: [
        {
          // path写法一:路径完整
          // path:'/home/hot',//二级路由路径
          // path写法二:直接写路径名,不能加/
          path: 'hot',
          component: Hot//二级路由
        },
        {
          path: 'agree',
          component: Agree
        },
        {
          path: 'more',
          component: More
        }
      ]
    },
    //·····
routerLink使用
javascript 复制代码
<template>
  <div>
    <!-- 轮播图 -->
    <div class="swiper">轮播图</div>
    <!-- 二级导航 -->
    <div class="subNav">
      <!-- 二级路由在使用时,必须把路径写完整 -->
      <router-link to="/home/hot">
        <h5>正在热卖</h5>
      </router-link>
      <router-link to="/home/agree">
        <h5>值得推荐</h5>
      </router-link>
      <router-link to="/home/more">
        <h5>查看更多</h5>
      </router-link>
    </div>
    //·····
设置二级路由使用位置
javascript 复制代码
<template>
  <div>
    <!-- 轮播图 -->
    <div class="swiper">轮播图</div>
    <!-- 二级导航 -->
    <div class="subNav">
      //·····
    </div>
    <!-- 路由组件显示位置 -->
     <div>
      <router-view />
     </div>
  </div>
</template>

路由配置项:name

可以给路由起一个名字,这样可以简化to的编写 ,且后期我们在prams传参,需要用到name

**第一步:**在路由关系中,添加name的配置
javascript 复制代码
 {
      path: 'agree',
      component: Agree,
      name: 'agree'
  },

**第二步:**使用name,简化to的写法

javascript 复制代码
  <!-- 二级导航 -->
    <div class="subNav">
      <!-- 二级路由在使用时,必须把路径写完整 -->
      <!-- to的写法一 -->
      <!-- <router-link to="/home/hot"> -->
      <!-- to的写法二 -->
      <!-- <router-link :to="{path:'/home/hot'}"> -->
      <!-- to的写法三 -->
      <router-link :to="{ name: 'hot' }">
        <h5>正在热卖</h5>
      </router-link>
      <router-link to="/home/agree">
        <h5>值得推荐</h5>
      </router-link>
      <router-link to="/home/more">
        <h5>查看更多</h5>
      </router-link>
    </div>
路由query传参

为了提高组件的复用性,可以给路由组件传参

**传递参数:**哪里点击跳转,在哪里传参数

需求:根据电影列表信息,点击不同的电影,查看不同的详情页面

第一步:配置好详情页组件

views/detail.vue

javascript 复制代码
<template>
    <div>
        <h1>detail</h1>
    </div>
</template>

<script>
export default {
    // 接收传递参数
    mounted(){
        // 当前的路由信息
        console.log(this.$route.query,'route');
    }
}
</script>

<style></style>
第二步:router/index.js
javascript 复制代码
routes: [
    {
        //路由重定向
        path: '/',//初始路径
        redirect: '/home/hot'
    },
    {
        path:'/detail',
        name:'detail',
        component:Detail
    },
    {
        //404页面
        path: '*',//初始路径
        component: '/404'
    },
  //·····
第三步:传递参数,哪里点击,哪里传递
javascript 复制代码
<template>
    <div>
        <ul class="fimls">
            <li v-for="item in fimls" :key="item.filmId">
                <!-- query传参:
                方式一:字符串拼接
                 语法:to="路由路径?参数名=参数值&参数名=参数值"
                方式二:对象的方式
                  语法::to="{
                        path:'路由路径',
                        query:{
                            参数名:参数值,
                            参数名:参数值
                        }
                     }" 
                -->
                <!-- <router-link to="/detail?a=1&b=2"> -->
                <!-- <router-link :to="`/detail?filmId=${item.filmId}`"> -->
                <router-link :to="{ path: '/detail', query: { filmId: item.filmId } }">
                    <img :src="item.poster" alt="" width="80" height="80">
                    <span>{{ item.name }}</span>
                </router-link>
            </li>
        </ul>
    </div>
</template>

<script>
import axios from 'axios';

export default {
    name: 'News',
    data() {
        return {
            fimls: []
        }
    },
    methods: {
        async getMovies() {
            let res = await axios({
                url: `https://m.maizuo.com/gateway?cityId=310100&pageNum=1&pageSize=10&type=1&k=9724615`,
                headers: {
                    "x-client-info": ' { "a": "3000", "ch": "1002", "v": "5.2.1", "e": "173211553215306425924321281", "bc": "310100" }',
                    "x-host": "mall.film-ticket.film.list"
                }
            })
            this.fimls = res.data.data.films
            console.log(this.fimls);

        }
    },

    created() {
        this.getMovies()

    }


}
</script>

<style>
.fimls {
    height: 500px;
    overflow: auto;
}
</style>
第四步:拿取数据

拿到detail组件的路由 this.$route.query ,里面就有传递的参数

javascript 复制代码
<template>
    <div>
        <h1>detail:{{ filmId }}</h1>
    </div>
</template>

<script>
export default {
    data() {
        return {
            filmId: ''
        }
    },
    // 接收传递参数
    mounted() {
        // 当前的路由信息
        console.log(this.$route.query, 'route');
        this.filmId = this.$route.query.filmId
        console.log(`通过filmId:${this.filmId}请求数据,进行展示`);
    }
}
</script>

路由params传参
**第一步:**新建好detail组件,并配置好路由关系

如果是采用to传递字符串的形式拼接参数: to='路径名/参数1/参数2' ,必须在route/index.js中路径处进行占位

javascript 复制代码
{
            // params传递,必须在路由后进行参数占位
            path:'/detail/:filmId/:num2',
            name: 'detail',
            component: Detail
        },

如果是to传递对象的形式:可以不占位

javascript 复制代码
{
            // params传递,必须在路由后进行参数占位
            // path:'/detail/:filmId/:num2',
            // 如果是对象的形式传参,就不需要占位
            path: '/detail',
            name: 'detail',
            component: Detail
        },
**第二步:**传递参数

哪里点击,哪里传递参数

javascript 复制代码
<template>
  <div>
    <ul>
      <li v-for="film in films" :key="film.filmId">
        <!-- params传参
          to='路径名/参数1/参数2' 
        -->
        <!-- 1、传递静态数据 -->
        <!-- <router-link to="/detail/123/456" class="film"> -->
        <!-- 2、传递动态的数据 -->
        <!-- <router-link :to="`/detail/${film.filmId}/456`" class="film"> -->
        <!-- 3、传递参数:对象的形式,不能用path,必须用name -->
        <router-link :to="{
          // path: '/detail',
          name: 'detail',
          params: {
            filmId: film.filmId,
            num2: 456
          }

        }" class="film">
          <img :src="film.poster" alt="" style="width: 100px;">
          {{ film.name }}
        </router-link>
      </li>
    </ul>
  </div>
</template>
**第三步:**detail组件接收参数

拿到当前组件的路由关系:this.$route.params

javascript 复制代码
<template>
    <div>
        <h1>detail:{{ filmId }}</h1>
    </div>
</template>

<script>
export default {
    data() {
        return {
            filmId: ''
        }
    },
    // 接收传递参数
    mounted() {
        // 当前的路由信息
        console.log(this.$route.params);
        this.filmId=this.$route.params.filmId
        
        // console.log(`通过filmId:${this.filmId}请求数据,进行展示`);
    }
}
</script>

路由的props

props配置主要是为了简化query和params参数的接收。让插值语法更加简洁。

哪个组件接收参数,就在哪个组件路由关系中配置props

三种写法:对象,函数,布尔值写法

javascript 复制代码
// 创建路由器对象(在路由器对象中配置路由)
const router = new VueRouter({
  routes: [
    // 路由1
    {
      name: "sub1",
      path: "/subject1/:a1/:a2/:a3",
      component: subject,
      第一种写法,对象的写法。只能传递固定值
      // props: { 
      //   x: "章三",
      //   y: "李四",
      //   z: "王二麻",
      // },
      第二种写法:函数式,这里的$route就是当前路由
      // props($route) {
      //   return {
      //     a1: $route.params.a1,
      //     a2: $route.params.a2,
      //     a3: $route.params.a3,
      //   };
      // },
      第三种写法:直接将params方式收到的数据转化为props,这种方式,只针对params传参
      props:true 
    },
    {
      name: "sub2",
      path: "/subject2/:a1/:a2/:a3",
      component: subject,
    },
  ],
});
// 暴露路由器对象
export default router;

subject.vue props接收,直接可以使用

javascript 复制代码
<template>
    <div>
        <ul class="web">
            <li>{{ a1 }}</li>
            <li>{{ a2 }}</li>
            <li>{{ a3 }}</li>
        </ul>
    </div>
</template>

<script>
export default {
    name: 'web',
    // 接收路由器中配置的props,简写插值语法的写法
    //props: ['x', 'y', 'z']
    props: ['a1', 'a2', 'a3']
}
</script>
<style>
.web {
    background-color: pink;
}
</style>
router-link的replace属性

浏览器的历史记录是存储在栈这种数据结构当中的。包括两种模式:

(1) push模式(默认的),有历史记录,可以返回上一个页面

(2) replace模式:没有历史记录,不能返回上个一个页面,例如支付页面,如果支付成功,是不允许再回退到支付界面的

开启replace模式

javascript 复制代码
a.<router-link  :replace="true"  to=""/>
b. <router-link replace />

编程式路由导航

需求中可能不是通过点击超链接的方式切换路由,也就是说不使用如何实现路由切换。

这种方式,我们叫声明式的路由导航

通过编写代码,完成路由组件的切换,这种方式我们呢交编程式路由导航

声明式路由导航可以通过相关API来完成:

(1) push模式:
javascript 复制代码
this.$router.push({
name : '',
query : {}
})
(2) replace模式:
javascript 复制代码
this.$router.replace({
name : '',
query : {}
})
(3) 前进:
javascript 复制代码
this.$router.forward()
(4) 后退:
javascript 复制代码
this.$router.back()
(5) 前进或后退几步:
javascript 复制代码
this.$router.go(2) 前进两步
this.$router.go(-2) 后退两步
(6) 使用编程式路由导航的时候,需要注意:

重复执行push或者replace的API时,会出现以下错误:

这个问题是因为push方法返回一个Promise对象,期望你在调用push方法的时候传递两个回调函数,一个是成功的回调,一个是失败的回调,如果不传就会出以上的错误。所以解决以上问题只需要给push和replace方法在参数上添加两个回调即可。

javascript 复制代码
....
goDetail(filmId) {
   //有历史记录
      this.$router.push({
        // path:'/detail',
        name: 'detail',
        params: {
          filmId: filmId,
          num2: 456
        },
         query: {
          filmId: filmId,
          num2: 456
        }
      }, () => { }, () => { })
....
缓存路由组件

默认情况下路由切换时,路由组件会被销毁。有时需要在切换路由组件时保留组件(缓存起来)。

javascript 复制代码
<keep-alive>//会缓存所有的路由组件
<router-view/>
</keep-alive>

通过添加以下3种属性,控制路由组件的缓存

include - 字符串或正则表达式或变成动态的属性,解析数组。只有名称匹配的组件会被缓存。

exclude - 字符串或正则表达式或变成动态的属性,解析数组。任何名称匹配的组件都不会被缓存。

max - 数字。最多可以缓存多少组件实例。

注意: router .js 中的name和vue 组件 的name需要保持一致

javascript 复制代码
<div class="mycontent">
      <!-- 告诉路由器,路由组件显示在这个位置 -->
      <!-- 1、只想news组件被缓存,其他组件切换时,还是被销毁  include-->
      <!-- 2、除了car组件,其他组件都被销毁 exclude -->
      <!-- <keep-alive include="news"> -->
      <!-- <keep-alive :include="['news']"> -->
      <keep-alive :exclude="['news']" >
        <router-view />
      </keep-alive>
    </div>
activated和deactivated

对于普通的组件来说,有8个生命周期函数,对于路由组件, 除了常规的8个,额外还有2个,

<keep-alive>包裹的路由组件,该组件有两个特有的生命周期函数:activated和deactivated。

activated在路由组件被激活时触发;

deactivated在路由组件失活时触发。

这两个钩子函数的作用是捕获路由组件的激活状态。

javascript 复制代码
<script>
需求:当组件切换到subject1的时候,每隔1s,输出一句话'工作中····'
当组件切走时,输出'休息中····',并解除定时器
正常情况下,这个功能可以用mounted和beforeDestroy去完成,但当subject1组件用keep-alive保持激活时,
就必须使用activated和deactivated组件了
export default {
    name: 'subject1',
    // mounted() {
    //     this.timer = setInterval(() => {
    //         console.log('工作中····');
    //     }, 1000)
    // },
    // beforeDestroy() {
    //     console.log('休息中···');
    //     clearInterval(this.timer)
    // }
    // 
    activated() {
        this.timer = setInterval(() => {
            console.log('工作中····');
        }, 1000)
    },
    deactivated() {
        clearInterval(this.timer)
        console.log('休息中');
    }
}
</script>

常用配置项

1. path ------ 路由匹配路径

作用:定义路由的 URL 路径,用于匹配浏览器地址栏的路径。

示例:

javascript 复制代码
path: '/user'、path: '/user/:id'(动态段)

在多级路由中:父级 path 作为基础路径,子级 path 拼接在后面(可省略开头的 /)。

2. component ------ 匹配时渲染的组件

作用:指定当前路由匹配时要渲染的 Vue 组件。

示例:

javascript 复制代码
component: Home、component: () => import('@/views/Home.vue')(懒加载)

在多级路由中:父路由的组件通常是一个布局组件(包含 <router-view>),子路由的组件是内容组件。

当一个页面有多个独立的 <router-view>(即多个路由出口)时,需要为每个出口指定不同的组件

使用 components 对象(注意是复数)

3. children ------ 嵌套子路由配置

作用:定义当前路由下的子路由,实现 UI 的嵌套。

类型:数组,每一项又是一个路由配置对象。

示例:

javascript 复制代码
children: [

  { path: 'profile', component: UserProfile }

]

访问 /user/profile 时,UserLayout 内的 <router-view> 会渲染 UserProfile。
4. name ------ 路由命名

作用:给路由起一个唯一的名字,方便编程式导航或声明式导航时使用。

示例:

javascript 复制代码
name: 'user'

使用:<router-link :to="{ name: 'user' }"> 或 $router.push({ name: 'user' })
5. redirect ------ 路由重定向

作用:访问当前路径时,自动跳转到另一个路径或路由。

示例:

javascript 复制代码
{ path: '/', redirect: '/home' }

{ path: '/a', redirect: { name: 'b' } }
6. alias ------ 路径别名

作用:让一个路由拥有多个访问路径。访问别名路径时,URL 会变化,但实际渲染的组件与原始路由相同。

示例:

javascript 复制代码
{ path: '/home', component: Home, alias: '/' }

访问 / 和 /home 都会渲染 Home 组件。

7. props ------ 将路由参数作为组件 props

作用:简化从 route.params 或 route.query 获取参数的方式,直接通过 props 接收。

三种模式:

javascript 复制代码
props: true ------ 将 params 作为 props 传入组件。

props: { ... } ------ 静态 props。

props: (route) => ({ ... }) ------ 函数模式,可返回 query/params 等。

示例:

javascript 复制代码
// 路由配置

{ path: '/user/:id', component: User, props: true }

// 组件中

props: ['id']  // 直接使用 this.id
8. meta ------ 路由元信息

作用:存储自定义数据,用于权限控制、页面标题、过渡动画等逻辑。

示例:

javascript 复制代码
{ path: '/admin', component: Admin, meta: { requiresAuth: true, title: '管理页' } }
javascript 复制代码
获取:$route.meta.requiresAuth
相关推荐
whuhewei2 小时前
js事件循环
前端·javascript
TheRouter2 小时前
构建一个支持多模型的 AI 聊天应用:React + TheRouter API 全栈教程
前端·人工智能·react.js
xiaofan11062 小时前
Pretext:无 DOM 的多行文本测量与排版库
前端·javascript
yuki_uix2 小时前
面试题里的 Custom Hook 思维:从三道题总结「异步状态管理」通用模式
前端·react.js·面试
cch89182 小时前
Vue-Element-Admin快速上手指南
前端·javascript·vue.js
hzxpaipai2 小时前
2026 杭州外贸网站制作公司哪家好?派迪科技确实有点技术
前端·科技·网络协议·网络安全
CHANG_THE_WORLD2 小时前
模拟解析:宽度数组 `[1,2,1]`,10个条目的 XRef 流
java·前端·算法
禅思院3 小时前
探索Vite深入 Rollup 分块插件:从零实现一个智能分包工具
前端·前端框架·vite
咕噜签名-铁蛋3 小时前
腾讯云ICP备案:变更主体&备案准备
前端·云计算·腾讯云