Vue ⑥-路由

单页应用程序

单页应用程序,即 Single-Page Application,简称 SPA ,是一种使用 JavaScript、HTML 和 CSS 构建的 Web 应用程序。SPA 的核心是前端路由,它使得用户在访问网站时,只需加载一次页面 ,然后通过前端路由来切换页面,而不需要重新加载整个页面。所有功能在 一个 html 页面 上实现

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

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

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

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

路由

生活中的路由:设备和 ip 的映射关系

比如路由器通过源 ip 和目的 ip 确定数据包的下一跳。

Vue中路由:路径组件映射 关系

VueRouter

目标:认识插件 VueRouter,掌握 VueRouter 的基本使用步骤

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

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

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

VueRouter 的 使用 (5 + 2)

5个基础步骤 (固定)

  1. 下载: 下载 VueRouter 模块到当前工程
bash 复制代码
npm install vue-router
  1. 创建 ./router/index.js 文件,引入 VueRouter 模块
js 复制代码
import VueRouter from 'vue-router'
  1. 安装注册
js 复制代码
Vue.use(VueRouter)
  1. 创建路由对象
js 复制代码
const router = new VueRouter()
  1. 注入,将路由对象注入到 new Vue 实例(main.js)中,建立关联
js 复制代码
import router from './router/index'

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

2 个核心步骤

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

这里创建 Find.vue My.vue Friend.vue 三个组件 (在 ./views 目录下)

  1. 配置路由规则,在 ./router/index.js 文件中配置路由规则
js 复制代码
import Find from './views/Find'
import My from './views/My'
import Friend from './views/Friend'

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

export default router
  1. 配置导航,配置路由出口(路径匹配的组件显示的位置),在 App.vue 文件中配置导航
html 复制代码
<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>

组件存放目录问题

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

路由相关的组件,为什么放在 views 目录呢?组件分类

组件分类 : .vue文件分2类: 页面组件 & 复用组件

分类开来 更易维护

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

声明式导航

导航链接

需求:实现导航高亮效果

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

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

<!-- 改成 -->
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/friend">朋友</router-link>

精准匹配 & 模糊匹配

说明:我们发现 router-link 自动给当前导航添加了 两个高亮类名

  • router-link-active模糊匹配 (用的多)

    • to="/my" 可以匹配 /my /my/a /my/b ...
  • router-link-exact-active精确匹配

    • to="/my" 仅可以匹配 /my

自定义高亮类名

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

语法:

js 复制代码
const router = new VueRouter({
  routes: [...],
  linkActiveClass: "类名1", // 模糊匹配
  linkExactActiveClass: "类名2" // 精确匹配
})

跳转传参

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

查询参数传参

语法格式如下:

  • to="/path?参数名=值"
  • 对应页面组件接收传递过来的值
    • $route.query.参数名

App.vue

html 复制代码
<template>
  <div id="app">
    <div class="link">
      <router-link to="/home">首页</router-link>
      <router-link to="/search">搜索页</router-link>
    </div>

    <router-view></router-view>
  </div>
</template>

router/index.js

js 复制代码
const router = new VueRouter({
  routes: [
    { path: '/home', component: Home },
    { path: '/search', component: Search }
  ]
})

Home.vue

html 复制代码
<div class="hot-link">
  热门搜索:
  <router-link to="/search?key=程序员">程序员</router-link>
  <router-link to="/search?ke=前端培训">前端培训</router-link>
  <router-link to="/search?key=如何成为前端大牛">如何成为前端大牛</router-link>
</div>

Search.vue

html 复制代码
<template>
  <div class="search">
    <p>搜索关键字: {{ $route.query.key }} </p>
    <p>搜索结果: </p>
    <ul>
      <li>.............</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'MyFriend',
  created () {
    // 在created中,获取路由参数
    // this.$route.query.参数名 获取
    console.log(this.$route.query.key)
  }
}
</script>
动态路由传参
  1. 配置动态路由,在 ./router/index.js 文件中配置路由规则
js 复制代码
const router = new VueRouter({
  routes: [
    { path: '/home', component: Home },
    { path: '/search/:words', component: Search }
  ]
})
  1. 配置导航链接:to="/path/参数值"

  2. 对应页面组件接收传递过来的值:$route.params.参数名

App.vue

html 复制代码
<template>
  <div id="app">
    <div class="link">
      <router-link to="/home">首页</router-link>
      <router-link to="/search">搜索页</router-link>
    </div>
    <router-view></router-view>
  </div>
</template>

Home.vue

html 复制代码
<div class="hot-link">
  热门搜索:
  <router-link to="/search/程序员">程序员</router-link>
  <router-link to="/search/前端培训">前端培训</router-link>
  <router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link>
</div>

Search.vue

html 复制代码
<template>
  <div class="search">
    <p>搜索关键字: {{ $route.params.words }} </p>
    <p>搜索结果: </p>
    <ul>
      <li>.............</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'MyFriend',
  created () {
    // 在created中,获取路由参数
    // this.$route.query.参数名 获取查询参数
    // this.$route.params.参数名 获取动态路由参数
    console.log(this.$route.params.words);
  }
}
</script>
动态路由参数可选符

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

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

js 复制代码
{ path: '/search/:words?', component: Search }
两种传参方式的区别

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

  • 跳转:to="/path?参数名=值&参数名2=值"
  • 获取:$route.query.参数名

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

  • 配置动态路由:path: "/path/:参数名"
  • 跳转:to="/path/参数值"
  • 获取:$route.params.参数名

路由重定向

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

说明:重定向 → 匹配path后, 强制跳转path路径

语法{ path: 匹配路径, redirect: 重定向到的路径 },

js 复制代码
const router = new VueRouter({
  routes: [
    { path: '/', redirect: '/home' }, // 重定向到 /home
    { path: '/home', component: Home },
    { path: '/search/:words?', component: Search }
  ]
})

404

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

位置:配在路由最后

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

js 复制代码
const router = new VueRouter({
  routes: [
    { path: '/', redirect: '/home' },
    { path: '/home', component: Home },
    { path: '/search/:words?', component: Search },
    { path: '*', component: NotFound }
  ]
})

模式设置

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

js 复制代码
const router = new VueRouter({
  mode: 'hash',
  routes: [...]
})
js 复制代码
const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

编程式导航

基本跳转

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

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

两种语法:

  • path 路径跳转(简易方便
js 复制代码
this.$router.push('路由路径')

this.$router.push({
  path: '路由路径'
})
  • name 命名路由跳转(适合 path 路径长的场景
js 复制代码
this.$router.push({
  name: '路由名'
})
js 复制代码
const router = new VueRouter({
  routes: [
    { name: '路由名', path: '/path/xxx', component: XXX },
  ]
})

Home.vue

html 复制代码
<template>
  <div class="home">
    <div class="logo-box"></div>
    <div class="search-box">
      <input type="text">
      <button @click="goSearch">搜索一下</button>
    </div>
    <div class="hot-link">
      热门搜索:
      <router-link to="/search/程序员">程序员</router-link>
      <router-link to="/search/前端培训">前端培训</router-link>
      <router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link>
    </div>
  </div>
</template>

<script>
export default {
  name: 'FindMusic',
  methods: {
    goSearch () {
      // 1. 通过路径的方式跳转
      // (1) this.$router.push('路由路径') [简写]
      // this.$router.push('/search')

      // (2) this.$router.push({     [完整写法]
      //         path: '路由路径' 
      //     })
      // this.$router.push({
      //   path: '/search'
      // })

      // 2. 通过命名路由的方式跳转 (需要给路由起名字) 适合长路径
      //    this.$router.push({
      //        name: '路由名'
      //    })
      this.$router.push({
        name: 'search'
      })
    }
  }
}
</script>

路由传参

问题:点击搜索按钮,跳转需要传参如何实现?

两种传参方式:查询参数 + 动态路由传参

两种跳转方式,对于两种传参方式都支持:

  • path 路径跳转传参(query传参)
js 复制代码
this.$router.push('/路径?参数名1=参数值1&参数2=参数值2')

this.$router.push({
  path: '/路径',
  query: {
    参数名1: '参数值1',
    参数名2: '参数值2'
  }
})
  • path 路径跳转传参 (动态路由传参)
js 复制代码
this.$router.push('/路径/参数值')

this.$router.push({
  path: '/路径/参数值'
})
  • name 命名路由跳转传参(query传参)
js 复制代码
this.$router.push({
  name: '路由名字',
  query: {
    参数名1: '参数值1',
    参数名2: '参数值2'
  }
})
  • name 命名路由跳转传参 (动态路由传参)
js 复制代码
this.$router.push({
  name: '路由名字',
  params: {
    参数名: '参数值'
  }
})

Home.vue

html 复制代码
<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/黑马程序员">黑马程序员</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 () {
      // 1. 通过路径的方式跳转
      // (1) this.$router.push('路由路径') [简写]
      //     this.$router.push('路由路径?参数名=参数值')
      // this.$router.push('/search')
      // this.$router.push(`/search?key=${this.inpValue}`)
      // this.$router.push(`/search/${this.inpValue}`)

      // (2) this.$router.push({     [完整写法] 更适合传参
      //         path: '路由路径'
      //         query: {
      //            参数名: 参数值,
      //            参数名: 参数值
      //         }
      //     })
      // this.$router.push({
      //   path: '/search',
      //   query: {
      //     key: this.inpValue
      //   }
      // })
      // this.$router.push({
      //   path: `/search/${this.inpValue}`
      // })



      // 2. 通过命名路由的方式跳转 (需要给路由起名字) 适合长路径
      //    this.$router.push({
      //        name: '路由名'
      //        query: { 参数名: 参数值 },
      //        params: { 参数名: 参数值 }
      //    })
      this.$router.push({
        name: 'search',
        // query: {
        //   key: this.inpValue
        // }
        params: {
          words: this.inpValue
        }
      })
    }
  }
}
</script>

组件缓存 keep-alive

问题:从面经 点到 详情页,又点返回,数据重新加载了 → 希望回到原来的位置

原因:路由跳转后,组件被销毁了,返回回来组件又被重建了,所以数据重新被加载了

解决:利用 keep-alive 将组件缓存下来

keep-alive 是什么

  • keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
  • keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。

keep-alive 的优点

  • 在组件切换过程中 把切换出去的组件保留在内存中,防止重复渲染 DOM
  • 减少加载时间及性能消耗,提高用户体验性。
html 复制代码
<template>
  <div class="h5-wrapper">
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

keep-alive 的三个属性

  • include : 组件名数组,只有匹配的组件会被缓存
  • exclude : 组件名数组,任何匹配的组件都不会被缓存
  • max : 最多可以缓存多少组件实例
html 复制代码
<template>
  <div class="h5-wrapper" :include="['LayoutPage']">
    <keep-alive >
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

keep-alive 的使用会触发两个生命周期函数

  • activated 当组件**被激活(使用)**的时候触发 → 进入这个页面的时候触发
  • deactivated 当组件不被使用的时候触发 → 离开这个页面的时候触发

组件缓存后就不会执行组件的created, mounted, destroyed 等钩子了

所以其提供了 activeddeactived 钩子,帮我们实现业务需求

js 复制代码
activated () {
  console.log('actived 激活 → 进入页面');
},
deactivated() {
  console.log('deactived 失活 → 离开页面');
} 

自定义创建项目

目标:基于 VueCli 自定义创建项目架子

的三个属性

  • include : 组件名数组,只有匹配的组件会被缓存
  • exclude : 组件名数组,任何匹配的组件都不会被缓存
  • max : 最多可以缓存多少组件实例
html 复制代码
<template>
  <div class="h5-wrapper" :include="['LayoutPage']">
    <keep-alive >
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

keep-alive 的使用会触发两个生命周期函数

  • activated 当组件**被激活(使用)**的时候触发 → 进入这个页面的时候触发
  • deactivated 当组件不被使用的时候触发 → 离开这个页面的时候触发

组件缓存后就不会执行组件的created, mounted, destroyed 等钩子了

所以其提供了 activeddeactived 钩子,帮我们实现业务需求

js 复制代码
activated () {
  console.log('actived 激活 → 进入页面');
},
deactivated() {
  console.log('deactived 失活 → 离开页面');
} 

自定义创建项目

目标:基于 VueCli 自定义创建项目架子

相关推荐
dualven_in_csdn1 小时前
搞了两天的win7批处理脚本问题
java·linux·前端
你的人类朋友1 小时前
✍️【Node.js程序员】的数据库【索引优化】指南
前端·javascript·后端
小超爱编程2 小时前
纯前端做图片压缩
开发语言·前端·javascript
银色的白2 小时前
工作记录:人物对话功能开发与集成
vue.js·学习·前端框架
应巅2 小时前
echarts 数据大屏(无UI设计 极简洁版)
前端·ui·echarts
萌萌哒草头将军3 小时前
🚀🚀🚀什么?浏览器也能修改项目源文件了?Chrome 团队开源的超强 Vite 插件!🚀🚀🚀
vue.js·react.js·vite
Jimmy3 小时前
CSS 实现描边文字效果
前端·css·html
islandzzzz3 小时前
HMTL+CSS+JS-新手小白循序渐进案例入门
前端·javascript·css·html
Senar3 小时前
网页中如何判断用户是否处于闲置状态
前端·javascript
很甜的西瓜4 小时前
typescript软渲染实现类似canvas的2d矢量图形引擎
前端·javascript·typescript·图形渲染·canvas