Vue2:路由1

简介: Vue2:路由1

Vue2:路由

Date: May 28, 2023

Sum: vue-router基本使用、高级用法


单页面应用程序

概念:SPA【Single Page Application】是指所有的功能都在一个html页面上实现


案例:


单页应用网站: 网易云音乐 https://music.163.com/


多页应用网站:京东 https://jd.com/


**单页应用 VS 多页面应用:

de292f22a1f90cdd04182dfad5a04a17.png

单页应用类网站:系统类网站 / 内部网站 / 文档类网站 / 移动端站点


多页应用类网站:公司官网 / 电商类网站


特点:


单页面应用程序将所有的功能局限于一个 web 页面中,仅在该 web 页面初始化时加载相应的资源( HTML、JavaScript 和 CSS)。


一旦页面加载完成了,SPA 不会因为用户的操作而进行页面的重新加载或跳转。而是利用JavaScript 动态地变换 HTML 的内容,从而实现页面与用户的交互。


注意:SPA它是按需更新的,并不是整体更新。因此,它需要更加关注访问路径与组件的对应关系


优点:


SPA 单页面应用程序最显著的 3 个优点如下:


① 良好的交互体验


单页应用的内容的改变不需要重新加载整个页面


获取数据也是通过 Ajax 异步获取


没有页面之间的跳转,不会出现“白屏现象”


② 良好的前后端工作分离模式


后端专注于提供 API 接口,更易实现 API 接口的复用


前端专注于页面的渲染,更利于前端工程化的发展


③ 减轻服务器的压力


服务器只提供数据,不负责页面的合成与逻辑的处理,吞吐能力会提高几倍


缺点:


任何一种技术都有自己的局限性,对于 SPA 单页面应用程序来说,主要的缺点有如下两个:


① 首屏加载慢


可以通过路由懒加载、代码压缩、CDN 加速、网络传输压缩处理


② 不利于 SEO


SSR 服务器端渲染


如何快速创建 vue 的 SPA 项目


vue 官方提供了两种快速创建工程化的 SPA 项目的方式:


① 基于 vite 创建 SPA 项目 ② 基于 vue-cli 创建 SPA 项目

ab1a2b1fef56baad95ff74a4040f183c.png

总结:


概念:一个Web网站中只有唯一一个HTML页面,所有的功能与交互都在这唯一的一个页面内完成。


特点:


1.集中所有功能于单页面中,仅在该页面初始化时加载相应的资源。


2.通过JS动态变换页面内容,从而实现页面与用户的交互


优点:


1.良好的交互体验


没有页面跳转,不会有“白屏”现象


2.良好的前后端分离模式


前端专注页面渲染,更利于前端工程化发展;后端专注提供API接口,更易实现API接口复用


3.减轻服务端的压力


服务器只提供数据,不负责页面的合成与逻辑,吞吐能力提高几倍


缺点:


1.首屏加载慢


可以通过代码压缩、CDN加速、路由懒加载、网络传输压缩处理等


2.不利于SEO


SSR服务器端渲染


前端路由的概念与原理

思考:

单页面应用程序,之所以开发效率高,性能好,用户体验好


最大的原因就是:页面按需更新

c783ec917ea9d5d27949d314b533d236.png



比如当点击【发现音乐】和【关注】时,只是更新下面部分内容,对于头部是不更新的


要按需更新,首先就需要明确:访问路径和 组件的对应关系!


访问路径 和 组件的对应关系如何确定呢? 路由


路由概念:

概念:路由(英文:router)就是对应关系。路由分为两大类: ① 后端路由 ② 前端路由


回顾:后端路由


后端路由指的是:请求方式、请求地址与 function 处理函数之间的对应关系。


在 node.js 课程中,express路由的基本用法如下:

6517ce602d4662df13b439371eff15df.png


前端路由:

SPA 与前端路由


SPA 指的是一个 web 网站只有唯一的一个 HTML 页面,所有组件的展示与切换都在这唯一的一个页面内完成。此时,不同组件之间的切换需要通过前端路由来实现。


结论:在 SPA 项目中,不同功能之间的切换,要依赖于前端路由来完成!


概念:Vue中的路由指 路径 与 组件 的映射关系,根据路由就能知道不同路径,应匹配渲染相应组件


通俗易懂的概念:Hash 地址与组件之间的对应关系。


我们点击不同的链接,会切换不同的哈希地址。当哈希地址切换,页面上就会展示对应组件。


工作方式:


① 用户点击了页面上的路由链接

② 导致了 URL 地址栏中的 Hash 值发生了变化

③ 前端路由监听了到 Hash 地址的变化

④ 前端路由把当前 Hash 地址对应的组件渲染都浏览器中

55a64b87af698d18d491c63d32df970c.png

结论:前端路由,指的是 Hash 地址与组件之间的对应关系!


实现简易的前端路由:


步骤1:导入并注册 MyHome、MyMovie、MyAbout 三个组件。示例代码如下:

import MyHome from './MyHome.vue'
import MyAbout from './MyAbout.vue'
import MyMovie from './MyMovie.vue'
export default {
  components: {
    MyHome, MyMovie, MyAbout,
  },
}

步骤2:通过 标签的 is 属性,动态切换要显示的组件。示例代码如下:

<template>
  <div>
    <h1>App.vue</h1>
    <component :is="comName">This is a test</component>
  </div>
</template>
export default {
  data() {
    return {
      comName: 'MyName', // 要展示的组件的名称
    }
  },
}

步骤3:在组件的结构中声明如下 3 个 链接,通过点击不同的 链接,切换浏览器地址栏中的 Hash 值:

<a href="#/home">Home</a>&nbsp;
<a href="#/movie">Movie</a>&nbsp;
<a href="#/about">About</a>

步骤4:在 created 生命周期函数中监听浏览器地址栏中 Hash 地址的变化,动态切换要展示的组件的名称:

window.onhashchange = () => {
    switch(location.hash) {
      case '#/home': // 点击了“首页”的链接
        this.comName = 'my-home'
        break
      case '#/movie': // 点击了“电影”的链接
        this.comName = 'my-movie'
        break
      case '#/about': // 点击了“关于”的链接
        this.comName = 'my-about'
        break
    }
  }
},

Code: App.vue

<template>
  <div>
    <h1>App.vue</h1>
    <a href="#/home">Home</a>&nbsp;
    <a href="#/movie">Movie</a>&nbsp;
    <a href="#/about">About</a>&nbsp;
    <hr />
    <component :is="comName">This is a test</component>
  </div>
</template>
<script>
import MyHome from '../01.easy-router/MyHome.vue'
import MyAbout from '../01.easy-router/MyAbout.vue'
import MyMovie from '../01.easy-router/MyMovie.vue'
export default {
  name: 'MyApp',
  data() {
    return {
      comName: 'MyName',
    }
  },
  components: {
    MyHome, MyMovie, MyAbout,
  },
  created() {
    window.onhashchange = () => {
      switch(location.hash) {
        case '#/home': // 点击了“首页”的链接
          this.comName = 'my-home'
          break
        case '#/movie': // 点击了“电影”的链接
          this.comName = 'my-movie'
          break
        case '#/about': // 点击了“关于”的链接
          this.comName = 'my-about'
          break
      }
    }
  },
}
</script>
<style lang="scss" scoped>
</style>

vue-router 的基本使用

基础概念:

概念:


vue-router 是 vue.js 官方给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项目中组件的切换。


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


版本:


vue-router 目前有 3.x 的版本和 4.x 的版本。其中:


vue-router 3.x 只能结合 vue2 进行使用


vue-router 4.x 只能结合 vue3 进行使用


vue-router 3.x 的官方文档地址:https://router.vuejs.org/zh/

vue-router 4.x 的官方文档地址:https://next.router.vuejs.org/


补充官网:https://v3.router.vuejs.org/zh/


说明:Vue 官方的一个路由插件,是一个第三方包


VueRouter 3.x的使用(5+2)

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


1-下载 VueRouter 模块到当前工程,版本3.6.5

yarn add vue-router@3.6.5
npm install vue-router@3.6.5

2-main.js中引入VueRouter

import VueRouter from 'vue-router'

3-安装注册

Vue.use(VueRouter)

4-创建路由对象

const router = new VueRouter()

5-注入,将路由对象注入到new Vue实例中,建立关联

new Vue({
  render: h => h(App),
  router:router
}).$mount('#app')

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

221860da670acce2a13cbff77724ee09.png

案例:


main.js

// 路由的使用步骤 5 + 2
// 5个基础步骤
// 1. 下载 v3.6.5
// yarn add vue-router@3.6.5
// 2. 引入
// 3. 安装注册 Vue.use(Vue插件)
// 4. 创建路由对象
// 5. 注入到new Vue中,建立关联
import VueRouter from 'vue-router'
Vue.use(VueRouter) // VueRouter插件初始化
const router = new VueRouter()
new Vue({
  render: h => h(App),
  router
}).$mount('#app')

**两个核心步骤:


1-创建需要的组件 (views目录),配置路由规则

275a3878ee49a17862b77780ea83e9fd.png

2-配置导航,配置路由出口(路径匹配的组件显示的位置)


代码中的router-view是用来匹配导航栏的位置的,如果它在代码的上/下面,那么导航栏也在上/下面


如下图所示:

d2801ec53bc2a0079b56952367dbb507.png

App.vue

<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>

案例:

f5b95a380218cd3627a45aa294d6b23e.png

Code:


main.js

import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
import Find from './views/Find'
import My from './views/My'
import Friend from './views/Friend'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
  // routes 路由规则们
  // route 一条路有规则 { path: 路径, component: 组件}
  routes: [
    { path: '/find', component: Find},
    { path: '/my', component: My},
    { path: '/friend', component: Friend},
  ]
})
Vue.config.productionTip = false
new Vue({
  render: h => h(App),
  router,
}).$mount('#app')

App.vue

<template>
  <div>
    <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>
  </div>
</template>
<script>
export default {};
</script>
<style>
body {
  margin: 0;
  padding: 0;
}
.footer_wrap {
  position: relative;
  left: 0;
  top: 0;
  display: flex;
  width: 100%;
  text-align: center;
  background-color: #333;
  color: #ccc;
}
.footer_wrap a {
  flex: 1;
  text-decoration: none;
  padding: 20px 0;
  line-height: 20px;
  background-color: #333;
  color: #ccc;
  border: 1px solid black;
}
.footer_wrap a:hover {
  background-color: #555;
}
</style>

vue-router 4.x的基本使用步骤:

vue-router 4.x 的基本使用步骤


① 在项目中安装 vue-router


② 定义路由组件


③ 声明路由链接和占位符


④ 创建路由模块


⑤ 导入并挂载路由模块


3.1 在项目中安装 vue-router


在 vue3 的项目中,只能安装并使用 vue-router 4.x。安装的命令如下:

npm install vue-router@next -S

注意:包名会被注册在package.json的dependencies里面,在生产环境下这个包的依赖依然存在。


3.2 定义路由组件


在项目中定义 MyHome.vue、MyMovie.vue、MyAbout.vue 三个组件,将来要使用 vue-router 来控制它们的展示与切换:


MyAbout, 其余同理:

<template>
  <h3>MyAbout</h3>
</template>
<script>
export default {
  name: 'MyAbout'
}
</script>
<style>
</style>

3.3 声明路由链接和占位符


可以使用 标签来声明路由链接,并使用 标签来声明路由占位符。


示例代码如下:

<template>
  <div>
    <h1>MyApp</h1>
    <!-- 声明路由链接 -->
    <router-link to="/home">首页</router-link>&nbsp;
    <router-link to="/movie">电影</router-link>&nbsp;
    <router-link to="/about">关于</router-link>
    <hr />
    <!-- 路由的占位符 -->
    <router-view></router-view>
  </div>
</template>

注意:在声明哈希属性时,需要用to属性来声明,而且哈希地址不再需要以#开头,vue中的router会自动为我们添加#。


3.4 创建路由模块


在项目中创建 router.js 路由模块,在其中按照如下 4 个步骤创建并得到路由的实例对象:


① 从 vue-router 中按需导入两个方法

② 导入需要使用路由控制的组件

③ 创建路由实例对象

④ 向外共享路由实例对象

⑤ 在 main.js 中导入并挂载路由模块


从 vue-router 中按需导入两个方法

// 1. 从 vue-router 中按需导入两个方法
// createRouter 方法用于创建路由的实例对象
// createWebHashHistory 用于指定路由的工作模式(hash模式)
import { createRouter, createWebHashHistory } from 'vue-router'

导入需要使用路由控制的组件

//2. 导入组件,这些组件将要以路由的方式,来控制它们的切换
import MyHome from './MyHome.vue'
import MyMoive from './MyMoive.vue'
import MyAbout from './MyAbout.vue'

创建路由实例对象

// 3. 创建路由实例对象
const router = createRouter({
  // 3.1 通过 history 属性指定路由的工作模式
  history: createWebHashHistory(),
  // 3.2 通过 routes 数组,指定路由规则
  routes: [
    // path 是 hash 地址, component 是要展示的组件
    { path: '/home', component: Home },
    { path: '/movie', component: Movie },
    { path: '/about', component: About },
  ]
})

向外共享路由实例对象

// 4. 向外共享路由实例对象,
//   供其他模块导入并使用
export default router

在 main.js 中导入并挂载路由模块

import { createApp } from 'vue'
import App from './components/App.vue'
import './index.css'
// 1. 导入路由模块
import router from './components/02.start/router'
const app = createApp(App)
// 2. 挂载路由模块
// app.use() 方法用来挂载“第三方的插件模块”
app.use(router)
app.mount('#app')

效果:

af94c893657274e244196ad2d4270a92.png


整体流程:

当我们点击电影时,地址栏会切换成 #/movie,当哈希地址发生变化,就会被路由模块所监听到,然后进行哈希地址的匹配:

// router.js
routes: [
    // path 是 hash 地址, component 是要展示的组件
    { path: '/home', component: MyHome },
    { path: '/movie', component: MyMovie },
    { path: '/about', component: MyAbout },
  ]

当匹配到,我们就会把相应的组件比如MyMovie放到App.vue中的路由占位符中

// App.vue
<template>
  <div>
    <h1>MyApp</h1>
    <!-- 声明路由链接 -->
    <router-link to="/home">首页</router-link>
    <router-link to="/movie">电影</router-link>
    <router-link to="/about">关于</router-link>
    <hr />
    <!-- 路由的占位符 -->
    <router-view></router-view>
  </div>
</template>

组件的存放目录问题

注意: .vue文件 本质无区别


组件分类:


.vue文件分为2类,都是 .vue文件(本质无区别)


页面组件 (配置路由规则时使用的组件)

复用组件(多个组件中都使用到的组件)

a1f4dad5613bac39f020dcf77fbc1cc1.png


存放目录:


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


1.src/views

文件夹页面组件 - 页面展示 - 配合路由用

2.src/components

文件夹复用组件 - 展示数据 - 常用于复用

路由的封装抽离

问题:所有的路由配置都在main.js中合适吗?


目标:将路由模块抽离出来。 好处:拆分模块,利于维护

25c2ddfadfb50006b2eddf6c65bcc9c1.png

路径简写:


脚手架环境下 @指代src目录,可以用于快速引入组件


具体书写:


index.js

import Find from '@/views/Find'
import My from '@/views/My'
import Friend from '@/views/Friend'
// 1. 导入Vue
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
  // routes 路由规则们
  // route 一条路有规则 { path: 路径, component: 组件}
  routes: [
    { path: '/find', component: Find},
    { path: '/my', component: My},
    { path: '/friend', component: Friend},
  ]
})
// 2. 导出
export default router

main.js

import Vue from 'vue'
import App from './App.vue'
// 3. 导入 router
import router from './router/index'
Vue.config.productionTip = false
new Vue({
  render: h => h(App),
  router,
}).$mount('#app')

App.vue

<template>
  <div>
    <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>
  </div>
</template>
<script>
export default {};
</script>
<style>
body {
  margin: 0;
  padding: 0;
}
.footer_wrap {
  position: relative;
  left: 0;
  top: 0;
  display: flex;
  width: 100%;
  text-align: center;
  background-color: #333;
  color: #ccc;
}
.footer_wrap a {
  flex: 1;
  text-decoration: none;
  padding: 20px 0;
  line-height: 20px;
  background-color: #333;
  color: #ccc;
  border: 1px solid black;
}
.footer_wrap a:hover {
  background-color: #555;
}
</style>

声明式导航

导航链接

需求:实现导航高亮效果

d4770417caadd47b5430467d2c1a2a59.png

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


**解决方案:


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


能跳转,配置 to 属性指定路径(必须) 。本质还是 a 标签 ,to 无需 #

能高亮,默认就会提供高亮类名,可以直接设置高亮样式

0e2695a316ecb177af0ab5747989a057.png

语法: 发现音乐

<div>
  <div class="footer_wrap">
    <router-link to="/find">发现音乐</router-link>
    <router-link to="/my">我的音乐</router-link>
    <router-link to="/friend">朋友</router-link>
  </div>
  <div class="top">
    <!-- 路由出口 → 匹配的组件所展示的位置 -->
    <router-view></router-view>
  </div>
</div>

通过router-link自带的两个样式进行高亮:

使用router-link跳转后,我们发现。当前点击的链接默认加了两个class的值 router-link-exact-active和router-link-active


我们可以给任意一个class属性添加高亮样式即可实现功能


代码:


Code:


App.vue

<template>
  <div>
    <div class="footer_wrap">
      <router-link to="/find">发现音乐</router-link>
      <router-link to="friend">我的音乐</router-link>
      <router-link to="my">我的朋友</router-link>
    </div>
    <div class="top">
      <!-- 路由出口 → 匹配的组件所展示的位置 -->
      <router-view></router-view>
    </div>
  </div>
</template>
<script>
export default {};
</script>
<style>
body {
  margin: 0;
  padding: 0;
}
.footer_wrap {
  position: relative;
  left: 0;
  top: 0;
  display: flex;
  width: 100%;
  text-align: center;
  background-color: #333;
  color: #ccc;
}
.footer_wrap a {
  flex: 1;
  text-decoration: none;
  padding: 20px 0;
  line-height: 20px;
  background-color: #333;
  color: #ccc;
  border: 1px solid black;
}
.footer_wrap a.router-link-active {
  background-color: purple;
}
.footer_wrap a:hover {
  background-color: #555;
}
</style>

两个类名

当我们使用跳转时,自动给当前导航加了两个类名

17be3b152ccd62c926b5a3c0c346d331.png

router-link-active

模糊匹配(用的多)


to=“/my” 可以匹配 /my /my/a /my/b …


只要是以/my开头的路径 都可以和 to="/my"匹配到


router-link-exact-active

精确匹配


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


在地址栏中输入二级路由查看类名的添加

d2515a60d6a95d34ab6a7f203a316ec4.png

理解:即使地址栏后面加上了 /one ,也就是所谓的二级地址,我们通过模糊匹配router-link-active


也能够让他变色。


自定义类名

问题:router-link的两个高亮类名 太长了,我们希望能定制怎么办

解决方案


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

const router = new VueRouter({
  routes: [...],
  linkActiveClass: "类名1",
  linkExactActiveClass: "类名2"
})

c1dc1c33d70d187cb2cb9482eb3b3ef5.png

详细操作过程:


Style:

.footer_wrap a.router-link-active {
  background-color: purple;
}

经过main.js配置过后

const router = new VueRouter({
  // routes 路由规则们
  // route  一条路由规则 { path: 路径, component: 组件 }
  routes: [
    { path: '/find', component: Find },
    { path: '/my', component: My },
    { path: '/friend', component: Friend },
  ],
  // link 自定义高亮
  linkActiveClass: 'active',
  linkExactActiveClass: 'exact-active'
})

style可以简化成如下:

.footer_wrap a.active {
  background-color: purple;
}

跳转传参:

目标:在跳转路由时,进行传参

eb0d61759114d385b809cac4544d7907.png

比如:当在搜索页点击了热门搜索链接,跳转到详情页,要把点击的内容带到详情页,该怎么办呢?


**跳转传参:


我们可以通过两种方式,在跳转的时候把所需要的参数传到其他页面中


查询参数传参

动态路由传参


**查询参数传参:

如何传参?

         .

如何接受参数固定用法:

        $router.query.参数名

案例:

b9387bf5cd9cd5a0330ce1d30cec0ec8.png

Code:


Home.vue

<template>
  <div class="home">
    <div class="logo-box"></div>
    <div class="search-box">
      <input v-model="inpValue" type="text">
      <button @click="goSearch">搜索一下</button>
    </div>
    <div class="hot-link">
      热门搜索:
      <router-link to="/search/黑马程序员?key=test">黑马程序员</router-link>
      <router-link to="/search/前端培训">前端培训</router-link>
      <router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link>
    </div>
  </div>
</template>
<script>
export default {
  name: 'FindMusic',
  data() {
    return {
      inpValue: '',
    }
  },
  methods: {
    goSearch() {
      this.$router.push(`/search${this.inpValue}`)
    }
  }
}
</script>
<style>
.logo-box {
  height: 150px;
  background: url('@/assets/logo.jpeg') no-repeat center;
}
.search-box {
  display: flex;
  justify-content: center;
}
.search-box input {
  width: 400px;
  height: 30px;
  line-height: 30px;
  border: 2px solid #c4c7ce;
  border-radius: 4px 0 0 4px;
  outline: none;
}
.search-box input:focus {
  border: 2px solid #ad2a26;
}
.search-box button {
  width: 100px;
  height: 36px;
  border: none;
  background-color: #ad2a26;
  color: #fff;
  position: relative;
  left: -2px;
  border-radius: 0 4px 4px 0;
}
.hot-link {
  width: 508px;
  height: 60px;
  line-height: 60px;
  margin: 0 auto;
}
.hot-link a {
  margin: 0 5px;
}
</style>

Search.vue

<template>
  <div class="search">
    <p>搜索关键字: {{ $route.query.key }}</p>
    <p>搜索结果: </p>
    <ul>
      <li>.............</li>
      <li>.............</li>
      <li>.............</li>
      <li>.............</li>
    </ul>
  </div>
</template>
<script>
export default {
  name: 'MyFriend',
  created () {
    // 在created中,获取路由参数
    // this.$route.query.参数名 获取
    console.log(this.$route.query.key);
  }
}
</script>
<style>
.search {
  width: 400px;
  height: 240px;
  padding: 0 20px;
  margin: 0 auto;
  border: 2px solid #c4c7ce;
  border-radius: 5px;
}
</style>

注意:如果在像created这种的js代码中,不要忘记加上this.


动态路由传参方式:


配置动态路由步骤:


1-配置动态路由

动态路由后面的参数可以随便起名,但要有语义

index.js

const router = new VueRouter({
  routes: [
    ...,
    { 
      path: '/search/:words', 
      component: Search 
    }
  ]
})

2-配置导航链接


Home.vue

to="/path/参数值"

3-对应页面组件接受参数


Search.vue

{{ $route.params.参数名 }}

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


案例:

2ac4acc06dc26f3bdc474a159bbaf047.png

Code:


index.js

import Home from '@/views/Home'
import Search from '@/views/Search'
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter) // VueRouter插件初始化
// 创建了一个路由对象
const router = new VueRouter({
  routes: [
    { path: '/home', component: Home },
    // *** 1, 配置动态路由
    { path: '/search/:words', component: Search }
  ]
})
export default router

Home.vue

// *** 2, 配置导航链接
<router-link to="/search/letstry">Vue-test</router-link>

Search.vue

<template>
  <div class="search">
    <!-- *** 3, 对应页面组件接收参数 -->
    <p>搜索关键字: {{ $route.params.words }}</p>
    <p>搜索结果: </p>
    <ul>
      <li>.............</li>
      <li>.............</li>
      <li>.............</li>
      <li>.............</li>
    </ul>
  </div>
</template>
<script>
export default {
  name: 'MyFriend',
  created () {
    // 在created中,获取路由参数
    // this.$route.query.参数名 获取
    console.log(this.$route.query.key);
  }
}
</script>
<style>
.search {
  width: 400px;
  height: 240px;
  padding: 0 20px;
  margin: 0 auto;
  border: 2px solid #c4c7ce;
  border-radius: 5px;
}
</style>

查询参数传参 VS 动态路由传参:


1.查询参数传参 (比较适合传多个参数)

  1.跳转:to=“/path?参数名=值&参数名2=值”

  2.获取:$route.query.参数名

2.动态路由传参 (优雅简洁,传单个参数比较方便)

  1.配置动态路由:path: “/path/:参数名”

  2.跳转:to=“/path/参数值”

  3.获取:$route.params.参数名

注意:动态路由也可以传多个参数,但一般只传一个


动态路由参数的可选符(了解)

问题:配了路由 path:“/search/:words” 为什么按下面步骤操作,会未匹配到组件,显示空白?

d4abf28c60598a2e5d36383984a018b7.png

原因:/search/:words 表示,必须要传参数。如果不传参数,也希望匹配,可以加个可选符"?"

const router = new VueRouter({
  routes: [
  ...
    { path: '/search/:words?', component: Search }
  ]
})

Vue路由

重定向

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

1f91ed6cca0b3ea5777236f814a73324.png

解决方案:重定向 → 匹配 / 后, 强制跳转 /home 路径


语法:

{ path: 匹配路径, redirect: 重定向到的路径 },
比如:
{ path:'/' ,redirect:'/home' }

代码:

const router = new VueRouter({
  routes: [
    { path: '/', redirect: '/home'},
   ...
  ]
})

404

**作用:**当路径找不到匹配时,给个提示页面


位置:404的路由,虽然配置在任何一个位置都可以,但一般都配置在其他路由规则的最后面

**语法:**path: “*” (任意路径) – 前面不匹配就命中最后这个

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

模式设置

问题:


路由的路径看起来不自然, 有#,能否切成真正路径形式?


hash路由(默认) 例如: http://localhost:8080/#/home

history路由(常用) 例如: http://localhost:8080/home (以后上线需要服务器端支持,开发环境webpack给规避掉了history模式的问题)

理解:


1-hash模式:底层是由a标签,锚链接实现的


2-history模式:由新增的HTML5中的historyAPI实现


语法:

const router = new VueRouter({
    mode:'histroy', //默认是hash
    routes:[]
})

注意:一旦采用了 histroy 模式,地址栏就没有 # ,需要后台配置访问规则


两种路由跳转方式

两种路径直接跳转

**问题:**点击按钮跳转如何实现?

f96deb9895c4dece3720dc28013491b4.png

**方案:**编程式导航:用JS代码来进行跳转


语法:


两种语法:


path 路径跳转 (简易方便)

name 命名路由跳转 (适合 path 路径长的场景)


path路径跳转语法:


特点:简易方便


Home.vue

//简单写法
this.$router.push('路由路径')
//eg
this.$router.push(`/search${this.inpValue}`)
//完整写法
this.$router.push({
  path: '路由路径'
})

代码:


Code:

export default {
  name: 'FindMusic',
  methods: {
    goSearch() {
      // Plan1: 简易写法
      // this.$router.push('/search')
      // Plan2: 完整写法
      this.$router.push({
        path: '/search'
      })
    }
  }
}

**name命名路由跳转:


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


语法:


路由规则,必须配置name配置项

index.js

{ name: '路由名', path: '/path/xxx', component: XXX },

通过name来进行跳转

Home.vue

this.$router.push({
  name: '路由名'
})

理解:给routes下的route起别名,方便自己之后push路径


代码演示通过name命名路由跳转:


Code:


index.js

{ name: 'test', path: '/search', component: Search}

Home.vue

export default {
  name: 'FindMusic',
  methods: {
    goSearch() {
      this.$router.push({
        name: 'search',
      })
    }
  }
}

问题:点击搜索按钮,跳转需要把文本框中输入的内容传到下一个页面如何实现?

eabdad5f8213579b77c7250e22824af3.png

**两种传参方式:


1.查询参数


2.动态路由传参



相关文章
|
18天前
|
JavaScript
【vue】如何跳转路由到指定页面位置
【vue】如何跳转路由到指定页面位置
19 0
|
1月前
|
JavaScript
vue路由导航守卫(全局守卫、路由独享守卫、组件内守卫)
vue路由导航守卫(全局守卫、路由独享守卫、组件内守卫)
41 0
|
2月前
vue3配置路由报错Catch all routes (“*“) must now be defined using a param with a custom regexp.
vue3配置路由报错Catch all routes (“*“) must now be defined using a param with a custom regexp.
55 0
|
20天前
|
资源调度 JavaScript 前端开发
Vue的路由管理:VueRouter的配置和使用
【4月更文挑战第24天】VueRouter是Vue.js的官方路由管理器,用于在单页面应用中管理URL路径与组件的映射。通过安装并引入VueRouter,设置路由规则和创建router实例,可以实现不同路径下显示不同组件。主要组件包括:`&lt;router-link&gt;`用于创建导航链接,`&lt;router-view&gt;`负责渲染当前路由对应的组件。此外,VueRouter还支持编程式导航和各种高级特性,如嵌套路由、路由参数和守卫,以应对复杂路由场景。
|
17天前
|
JavaScript 数据可视化 算法
vue3+threejs可视化项目——搭建vue3+ts+antd路由布局(第一步)
vue3+threejs可视化项目——搭建vue3+ts+antd路由布局(第一步)
36 6
|
4天前
|
JavaScript
vue中watch监听路由传来的参数变化问题
vue中watch监听路由传来的参数变化问题
6 0
|
6天前
|
缓存 JavaScript
在 Vue 组件中使用计算属性和侦听器来响应路由变化
Vue Router 中,计算属性和侦听器常用于根据路由变化更新组件状态。计算属性缓存依赖,当路由参数改变时自动更新,如示例中的 `userId`。侦听器则监听 `$route` 变化,执行相应操作,例如在 `currentUserId` 示例中响应 `userId` 更新。计算属性适合简单变化,而异步操作或复杂场景可选用侦听器。Vue 3 中,`watchEffect` 减少了部分侦听场景的复杂性。总之,它们用于组件内部响应路由变化,而非直接处理路由逻辑。
12 4
|
14天前
|
资源调度 JavaScript 前端开发
【vue】vue中的路由vue-router,vue-cli脚手架详细使用教程
【vue】vue中的路由vue-router,vue-cli脚手架详细使用教程
|
14天前
|
JavaScript Go
Vue路由跳转及路由传参
Vue路由跳转及路由传参
|
18天前
|
JavaScript 前端开发
vue3+ts+element home页面侧边栏+头部组件+路由组件组合页面教程
这是一个Vue.js组件代码示例,展示了带有侧边栏导航和面包屑导航的布局。模板中使用Element Plus组件库,包含可折叠的侧边栏,其中左侧有 Logo 和导航列表,右侧显示更具体的子菜单。`asideDisplay`控制侧边栏宽度。在`script`部分,使用Vue的响应式数据和生命周期钩子初始化路由相关数据,并从localStorage恢复状态。样式部分定义了组件的颜色、尺寸和布局。
19 1