前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue路由

Vue路由

作者头像
用户11097514
发布2024-05-31 12:21:24
2110
发布2024-05-31 12:21:24
举报
文章被收录于专栏:技术分享技术分享

引言

什么是单页应用程序: 单页应用程序:SPA【Single Page Application】是指所有的功能都在一个html页面上实现

单页应用和多页应用的区别:

image.png
image.png

单页面应用程序,之所以开发效率高,性能好,用户体验好 最大的原因就是:页面按需更新

路由的基本使用

定义&作用:

修改地址栏路径时,切换显示匹配的组件

基本使用

固定5个固定的步骤(不用死背,熟能生巧)

  1. 下载 VueRouter 模块到当前工程,版本3.6.5
代码语言:javascript
复制
npm install vue-router@3.6.5
  1. main.js中引入VueRouter
代码语言:javascript
复制
import VueRouter from 'vue-router'
  1. 安装注册
代码语言:javascript
复制
Vue.use(VueRouter)
  1. 创建路由对象
代码语言:javascript
复制
const router = new VueRouter()
  1. 注入,将路由对象注入到new Vue实例中,建立关联
代码语言:javascript
复制
new Vue({
  render: h => h(App),
  router:router
}).$mount('#app')

当我们配置完以上5步之后 就可以看到浏览器地址栏中的路由 变成了 /#/的形式。表示项目的路由已经被Vue-Router管理了

核心步骤

  1. 创建需要的组件 (views目录),配置路由规则
image.png
image.png
  1. **配置导航,配置路由出口(路径匹配的组件显示的位置) **

这里我们在App.vue中配置

代码语言:javascript
复制
<div class="footer_wrap">
  <a href="#/find">发现音乐</a>
  <a href="#/my">我的音乐</a>
  <a href="#/friend">朋友</a>
</div>
<div class="top">
  <router-view></router-view>
</div>

放置位置:

分类开来的目的就是为了 更易维护

  1. src/views文件夹页面组件 - 页面展示 - 配合路由用
  2. src/components文件夹复用组件 - 展示数据 - 常用于复用

路由进阶

路由模块封装

如果将所有的路由配置 都配配置在main.js中, 那么如果模块很多, 那么项目就不利于维护, 所以我们需要拆分路由模块

image.png
image.png

router/index.js的内容

代码语言:javascript
复制
// 路由的使用步骤 5 + 2
// 5个基础步骤
// 1. 下载 v3.6.5
// 2. 引入
// 3. 安装注册 Vue.use(Vue插件)
// 4. 创建路由对象( 也就是一些组件 )
// 5. 注入到new Vue中,建立关联

// 2个核心步骤
// 1. 建组件(views目录),配规则
// 2. 准备导航链接,配置路由出口(匹配的组件展示的位置) 

//@ 代表的就是src
import Find from '@/views/Find'
import My from '@/views/My'
import Friend from '@/views/Friend'
import Link from '@/views/Link'
import VueRouter from 'vue-router'

import Vue from 'vue'
Vue.use(VueRouter) // VueRouter插件初始化

const router = new VueRouter({
  // routes 路由规则们
  // route  一条路由规则 { path: 路径, component: 组件 }
  routes: [
    { path: '/find', component: Find },
    { path: '/my', component: My },
    { path: '/friend', component: Friend },
    {path: '/link', component: Link}
  ]
})


export default router

声明式导航& 导航高亮 / 精确匹配 / 自定义高亮类名

导航高亮

image.png
image.png

如果使用a标签进行跳转的话,需要给当前跳转的导航加样式,同时要移除上一个a标签的样式,太麻烦!!!

vue-router 提供了一个全局组件 router-link (取代 a 标签)

  • 能跳转,配置 to 属性指定路径(必须) 。本质还是 a 标签 ,to 无需 #
  • 能高亮,默认就会提供高亮类名,可以直接设置高亮样
代码语言:javascript
复制
<div class="footer_wrap">
  <router-link to="/find">发现音乐</router-link>
  <router-link to="/my">我的音乐</router-link>
  <router-link to="/friend">朋友</router-link>
</div>

使用router-link跳转后,我们发现。当前点击的链接默认加了两个class的值 router-link-exact-active和router-link-active 我们可以给任意一个class属性添加高亮样式即可实现功能

代码语言:javascript
复制
<style>
.footer_wrap a.router-link-active {
  background-color: purple;
} 
</style>

两个类名

当我们使用router-link跳转时,自动给当前导航加了**两个类名. ** 相当于a标签加上了两个类名

image.png
image.png
精确匹配:router-link-exact-active

to=”/my” 仅可以匹配 /my

不能对其他的路径起作用。

模糊匹配: router-link-active

to=”/my” 可以匹配 /my /my/a /my/b …. 只要是以/my开头的路径 都可以和 to=”/my”匹配到

image.png
image.png

就是如果我们匹配到发现音乐下面的排行榜名 ,但是同时还希望 发现音乐也是高亮显示, 那么我们就可以通过使用模糊匹配的方式来实现

自定义类名

对于router-link-exact-activerouter-link-active, 认为类名太长了,如果想要换的短一些, 可以通过使用下面的即可

我们可以在创建路由对象时,额外配置两个配置项即可。 linkActiveClass和linkExactActiveClass

代码语言:javascript
复制
const router = new VueRouter({
  routes: [...],
  linkActiveClass: "类名1", 
  linkExactActiveClass: "类名2"
  })
代码语言:javascript
复制
// 创建了一个路由对象
    const router = new VueRouter({
    routes: [
    ...
    ], 
    linkActiveClass: 'active', // 配置模糊匹配的类名
    linkExactActiveClass: 'exact-active' // 配置精确匹配的类名
    })

最后再将style中之前配置的 router-link-exact-active更改为自己使用的类名1类名2即可。

声明式导航的跳转传参的两种方式

在跳转路由时,进行传参 比如:现在我们在搜索页点击了热门搜索链接,跳转到详情页,需要把点击的内容带到详情页,改怎么办呢?

  • 查询参数传参
  • 动态路由传参

查询参数传参

语法格式:<router-link to="to/path?参数名=值"> </router-link>对应的页面接收参数的语法:<p>{{

动态路由传参

  1. 配置动态路由动态路由后面的参数可以随便起名,但要有语义
代码语言:javascript
复制
const router = new VueRouter({
  routes: [
    ...,
    // /search/:参数名 表示,必须要传参数。如果不传参数,也希望匹配,可以加个可选符"?"  
    {  path: '/search/:参数名', component: Search  }
  ]
})	
  1. 配置导航链接to="/path/参数值"

可以直接写参数名, 不需要写 ?key=value

  1. 对应页面组件接受参数$route.**params**.参数名

params后面的参数名要和动态路由配置的参数保持一致

两种传参数的方式区别

  1. 查询参数传参 (比较适合传多个参数)
  2. 跳转:to=”/path?参数名=值&参数名2=值”
  3. 获取:$route.query.参数名
  4. 动态路由传参 (优雅简洁,传单个参数比较方便)
    1. 配置动态路由:path: “/path/:参数名”
    2. 跳转:to=”/path/参数值”
    3. 获取:$route.params.参数名
  5. 注意:动态路由也可以传多个参数,但一般只传一个

路由重定向 / 路由404 / 路由模式

路由重定向

网页打开时, url 默认是 / 路径,未匹配到组件时,会出现空白

image.png
image.png

重定向 → 匹配 / 后, 强制跳转 /home 路径

代码语言:javascript
复制
{ path: 匹配路径, redirect: 重定向到的路径 },
比如:
{ path:'/' ,redirect:'/home' }
代码语言:javascript
复制
const router = new VueRouter({
  routes: [
    { path: '/', redirect: '/home'},
 	 ...
  ]
})

路由404

找不到路径匹配的时候, 通过404的路由,虽然配置在任何一个位置都可以,但一般都配置在其他路由规则的最后面

代码语言:javascript
复制
import NotFind from '@/views/NotFind'

const router = new VueRouter({
  routes: [
    ...
    { path: '*', component: NotFind } //最后一个
  ]
})

路由模式

默认是hash模式, 就是带 # 的 路由的路径看起来不自然, 有#,能否切成真正路径形式?

2.语法

代码语言:javascript
复制
const router = new VueRouter({
  mode:'histroy', //默认是hash , 通过这个配置就是设置成为history
  routes:[]
})

编程式导航- 两种路由跳转方式

点击按钮跳转。 通过js的格式 实现跳转

image.png
image.png

两种语法:

  • path 路径跳转 (简易方便)
  • name 命名路由跳转 (适合 path 路径长的场景)

path的形式进行跳转

通过点击事件触发

代码语言:javascript
复制
methods: { 
	clickItem() {
     //两种方法
    //1. 简单写法
    this.$router.push('路由路径')
    //2. 完整写法
    this.$router.push({
      path: '路由路径'
    })
  }

}

name命名路由跳转

特点:适合 path 路径长的场景

语法:

  • 路由规则,必须配置name配置项
代码语言:javascript
复制
const router = new VueRouter({
  // routes 路由规则们
  // route  一条路由规则 { path: 路径, component: 组件 }
  routes: [
    { name: '路由名', path: '/path/xxx', component: XXX },
  ]
})
  • 通过click事件触发之后 然后通过 name来进行跳转
代码语言:javascript
复制
methods: { 
	clickItem() {
     this.$router.push({
      name: '路由名'
    })
  }
}

路由跳转的传参

下面的演示案例,都是通过点击事件触发的, 所以使用clickItem函数来实现其中的传参

  1. path路径的方式 (query的方式)
代码语言:javascript
复制
methods: { 
	clickItem() {
    //简单写法
    this.$router.push('/路径?参数名1=参数值1&参数2=参数值2')
    //完整写法
    this.$router.push({
      path: '/路径',
      query: {
        参数名1: '参数值1',
        参数名2: '参数值2'
      }
    })
  }
}

接受还是通过$route.query.参数名

  1. path路径的方式, 通过动态路由的方式
代码语言:javascript
复制
  
methods: { 
	clickItem() {
    //简单写法
    this.$router.push('/路径/参数值')
    //完整写法
    this.$router.push({
      path: '/路径/参数值'
    })
  }
}

接受参数的方式依然是:$route.params.参数值

  1. name 命名路由跳转传参 (query传参)
代码语言:javascript
复制

methods: { 
	clickItem() {
  this.$router.push({
      name: '路由名字',
      query: {
        参数名1: '参数值1',
        参数名2: '参数值2'
      }
    })
  }
}
  1. name 命名路由跳转传参 (动态路由传参)
代码语言:javascript
复制
methods: { 
	clickItem() {
    this.$router.push({
      name: '路由名字',
      params: {
        参数名: '参数值',
      }
    })

  }
}

案例实现

**分析:配路由 + 实现功能 **

  1. **配路由 **

① 首页 和 面经详情,两个一级路由 ② 首页内嵌四个可切换页面 (嵌套二级路由)

  1. 实现功能

① 首页请求渲染 ② 跳转传参 到 详情页,详情页渲染 ③ 组件缓存,优化性能

image.png
image.png

配置路由

  1. 首先配置两个一级路由

在Vouter.js中 , 通过导入 并且配置路由信息

代码语言:javascript
复制
import Vue from 'vue'
import VueRouter from "vue-router";
//1. 导入
import Layout from '@/views/Layout'
import ArticleDetail from '@/views/ArticleDetail'


Vue.use(VueRouter)

//2. 配置路由
const router = new VueRouter({
  routes: [
    { path: '/', component: Layout },
    {path: '/detail', component: ArticleDetail}
  ]
})

export default router
  1. 配置首页内嵌的四个二级路由

如果按照上面的配置, 那么首页的内容就无法展示, 二级路由 和 一级路由就成为同等级的路由 所以我们需要通过使用children 来进行配置

代码语言:javascript
复制
//1.1 导入二级路由
import Article from '@/views/Article' 
import Collect from '@/views/Collect'
import Like from '@/views/Like'
import User from '@/views/User'

Vue.use(VueRouter)

//2. 配置路由
const router = new VueRouter({
  routes: [
    { 
      path: '/', 
      component: Layout ,
      //2.1 配置当前路由嵌套的二级路由
      children: [
        {
          path : '/article',
          component: Article
        },
        {
          path: '/like',
          component: Like
        },
        {
          path: 'collect',
          component: Collect
        },
        {
          path: 'user',
          component: User
        }
      ]
    },
    {path: '/detail', component: ArticleDetail}
  ]
})

但是仅仅这样配置还不够,我们还需要在一级路由的文件中配置二级路由的出口 ,通过这样就可以实现路由的配置

这里一级路由是Layout.vue 二级路由是 tabbar下面的四个

代码语言:javascript
复制
<template>
  <div class="h5-wrapper">
    <div class="content">
      <!-- 配置二级路由的出口 -->
      <router-view></router-view>
    </div>
    <nav class="tabbar">
      <a href="#/article">面经</a>
      <a href="#/collect">收藏</a>
      <a href="#/like">喜欢</a>
      <a href="#/user">我的</a>
    </nav>
  </div>
</template>

实现导航的高亮效果

  1. 将a标签替换成为 router-link(to)
  2. 结合高亮类名 通过css实现高亮效果
代码语言:javascript
复制
<template>
  <div class="h5-wrapper">
    <div class="content">
      <!-- 配置二级路由的出口 -->
      <router-view></router-view>
    </div>
    <nav class="tabbar">
      <router-link to="#/article">面经</router-link>
      <router-link to="#/collect">收藏</router-link>
      <router-link to="#/like">喜欢</router-link>
      <router-link to="#/user">我的</router-link>
    </nav>
  </div>
</template>
代码语言:javascript
复制
<style>
 a.router-link-active {
      color: orange;
    }
</style>

实现对应的功能

内容1. 实现首页内容的显示

这里我们实现的是首页的基础内容渲染

Article.vue中 ,实现显示页面的所有内容

代码语言:javascript
复制
<template>
  <div class="article-page">
    
    <div class="article-item"  
    v-for="(item, index) in articelList" 
    :key="item.id" 
    @click="$router.push('/detail')">
      <div class="head">
        <img :src="item.creatorAvatar">
        <div class="con">
          <p class="title">{{ item.stem }}</p>
          <p class="other">{{ item.creatorName }}| {{ item.createdAt }}</p>
        </div>
      </div>
      <div class="body">
        {{ item.content }}
      </div>
      <div class="foot">点赞 {{ item.likeCount }} | 浏览 {{ item.views }}</div>
    </div>
  </div>
</template>

<script>
import axios from 'axios'
// 请求地址: https://mock.boxuegu.com/mock/3083/articles
// 请求方式: get
export default {
  name: 'ArticlePage',
  data () {
    return {
      // 接收发送的数据
      articelList: [],
    }
  },
  // 获取请求数据
  async created() {
    const articles = await axios.get('https://mock.boxuegu.com/mock/3083/articles')
    //存入
    console.log("test")
    console.log(articles)
    // 页面渲染
    this.articelList = articles.data.result.rows
  } ,
  //在页面挂载阶段进行页面渲染
  mounted (){ 
  }
}
</script>

内容2. 实现点击显示详细的内容

通过点击事件进行跳转, 并且在跳转的同时需要携带内容的参数

在文章列表中页中, 通过点击事件@click="

代码语言:javascript
复制
<template>
  <div class="article-page">
    
    <div class="article-item"  
    v-for="(item, index) in articelList" 
    :key="item.id" 
    @click="$router.push(`/detail/${item.id}`)">
      <div class="head">
        <img :src="item.creatorAvatar">
        <div class="con">
          <p class="title">{{ item.stem }}</p>
          <p class="other">{{ item.creatorName }}| {{ item.createdAt }}</p>
        </div>
      </div>
      <div class="body">
        {{ item.content }}
      </div>
      <div class="foot">点赞 {{ item.likeCount }} | 浏览 {{ item.views }}</div>
    </div>
  </div>
</template>
动态路由传参
  1. 配置路由参数 {path: '/detail/:id', component: ArticleDetail}
  2. 点击携带路由参数

@click=”router.push(/detail/{item.id})”

  1. Article详情页面通过 this.$route.params.id 来接受数据
点击返回调转到上一个页面
image.png
image.png

通过routerback返回 <nav class="nav"><span class="back" @click="$router.back()">&lt;</span> 面经详情</nav>

渲染页面

通过得到的传过来的请求参数, 然后再通过axios进行发送请求 ,最后将得到的数据。 最后将数据渲染到页面上

内容3. 组件缓存Keep- alive

问题:

从面经列表 点到 详情页,又点返回,数据重新加载了 但是我们希望回到原来的位置

原因:

当路由被跳转后,原来所看到的组件就被销毁了(会执行组件内的beforeDestroy和destroyed生命周期钩子),重新返回后组件又被重新创建了(会执行组件内的beforeCreate,created,beforeMount,Mounted生命周期钩子),所以数据被加载了

解决方案: 利用keep-alive把原来的组件给缓存下来

keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件中。 优点: 在组件切换过程中把切换出去的组件保留在内存中,防止重复渲染DOM, 减少加载时间及性能消耗,提高用户体验性。

缓存所有的内容

代码语言:javascript
复制
<template>
  <div class="h5-wrapper">
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

但是这样会导致所有的内容都被缓存, 容易出现乱序的现象 所以需要配置<keep-alive>的属性

keep-alive的三个属性

① include : 组件名数组,只有匹配的组件会被缓存 ② exclude : 组件名数组,任何匹配的组件都不会被缓存 ③ max : 最多可以缓存多少组件实例

组件名 就是该组件中的 name, 如果没有name 才会找文件名作为组件名数组

代码语言:javascript
复制
<template>
  <div class="h5-wrapper">
    <keep-alive :include="keepArr">
      <router-view></router-view>

    </keep-alive>
  </div>
</template>

<script>
export default {
  name: "h5-wrapper",
  data() { 
    return {
      // 缓存组件的数组
      keepArr: ['LayoutPage']
    }
  }
}
</script>

通过:include就可以实现对指定组件的缓存

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
    • 单页应用和多页应用的区别:
    • 路由的基本使用
      • 定义&作用:
        • 基本使用
          • 核心步骤
            • 放置位置:
            • 路由进阶
              • 路由模块封装
                • 声明式导航& 导航高亮 / 精确匹配 / 自定义高亮类名
                  • 导航高亮
                  • 两个类名
                  • 自定义类名
                  • 声明式导航的跳转传参的两种方式
                  • 查询参数传参
                  • 动态路由传参
                  • 两种传参数的方式区别
                • 路由重定向 / 路由404 / 路由模式
                  • 路由重定向
                  • 路由404
                  • 路由模式
                  • 2.语法
                • 编程式导航- 两种路由跳转方式
                  • path的形式进行跳转
                  • name命名路由跳转
                  • 路由跳转的传参
              • 案例实现
                • 配置路由
                  • 实现导航的高亮效果
                    • 实现对应的功能
                      • 内容1. 实现首页内容的显示
                      • 内容2. 实现点击显示详细的内容
                      • 内容3. 组件缓存Keep- alive
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档