路由 之 再识

优势

  • 传统的多页面应用程序,每次请求服务器返回的都是一整个完整的页面

  • 单页面应用程序只有第一次会加载完整的页面

  • 以后每次请求仅仅获取必要的数据,减少了请求体积,加快页面响应速度,降低了对服务器的压力

  • SPA更好的用户体验,运行更加流畅

缺点

  1. 开发成本高 (需要学习路由) vue-router react-router

  2. 不利于 SEO 搜索引擎优化 谷歌浏览器在解决这个问题 ssr:服务端渲染 server side rendering

路由介绍

  • 路由 : 是浏览器 URL 中的哈希值( # hash) 与 展示视图内容(组件) 之间的对应规则

    • 简单来说,路由就是一套映射规则(一对一的对应规则), 由开发人员制定规则.-

    • 当 URL 中的哈希值( # hash) 发生改变后,路由会根据制定好的规则, 展示对应的视图内容(组件)

  • 为什么要学习路由?

    • 渐进式 =>vue => vuer-router (管理组件之间的跳转)

    • 在 web App 中, 经常会出现通过一个页面来展示和管理整个应用的功能.

    • SPA 往往是功能复杂的应用,为了有效管理所有视图内容,前端路由 应运而生.

  • vue 中的路由 : 是 hashcomponent 的对应关系, 一个哈希值对应一个组件

路由基础01

1. 前端路由 - 工作模式原理

基本思路:

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

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

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

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

<template>
 <div>
   <a href="#one">ONE</a>
   <a href="#two">TWO</a>
   <a href="#three">THREE</a>

   <component :is="is"></component>
 </div>
</template>

created() {
   window.onhashchange = () => {
       console.log(location.hash.slice(1))
       this.is = location.hash.slice(1)
  }
},

2. 路由的基本使用

  • 安装 : yarn add vue-router

2.1 准备工作( 3个 )

  • 引入

import VueRouter from 'vue-router'
// 把路由当成插件一样安装
Vue.use(VueRouter)
  • 实例路由对象 : let router = new VueRouter()

  • 把路由挂载到vue实例上

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

2.2 具体步骤 ( 3个 )

  • 1.入口

  • 2.规则

  • 3.出口


# 1. 入口
 // 浏览器 url 地址栏 ==>   #/one   和   #/two

# 2. 路由规则
// path : 路由路径
// component : 将来要展示的路由组件
routes: [
  { path: '/one', component: One },
  { path: '/two', component: Two }
]

# 3. 出口
<router-view></router-view>
  • 画图 逻辑


# 总结
拿到入口哈希路径, 根据路由匹配规则,找到对应的组件,显示到对应的出口位置

3. 声明式导航


<!-- 1. 改变入口 -->
<router-link to='/one'>one</router-link>
<router-link to='/two'>two</router-link>

4. 让当前导航高亮 (精确匹配 和 模糊匹配)

需求: 点击切换后, 让当前导航高亮


.router-link-exact-active, .router-link-active{
     color: red;
     font-size: 50px;
}

5 演示高亮问题


// 地址栏 输入 / 或者 /two 会有问题的 或者点击演示
<router-link to="/">one</router-link>
<router-link to="/two">two</router-link>
  • 精确匹配 : router-link-exact-active 类名 : 只有当 浏览器地址栏中的哈希值 与 router-link 的 to 属性值,完全匹配对,才会添加该类 ( 上 == 下 )

  • 模糊匹配: router-link-active 类名 : 只要 浏览器地址栏中的哈希值 包含 router-link 的 to 属性值,就会添加该类名 (上 > 下)

  • 解决办法1 : 只使用精确匹配


.router-link-exact-active {
 color: red;
 font-size: 30px;
}
  • 解决方法2 : 添加 exact (推荐)


.router-link-exact-active,
.router-link-active {
color: red;
font-size: 30px;
}

<router-link to="/" exact>one</router-link>
<router-link to="/two">two</router-link>

路由基础02

1. 动态路由

  • 基本使用


# 入口
<router-link to="/detail/1">手机1</router-link>
<router-link to="/detail/2">手机2</router-link>
<router-link to="/detail/3">手机3</router-link>
<router-link to="/detail">手机4</router-link> 没有参数如何????


# 规则
routes: [
 // 2 . 路由规则
{ path: '/detail/:id?', component: Detail }
]

# 获取参数的两种方式
<template>
 <div>
   <h1>one {{ $route.params.id }}</h1>
 </div>
</template>

<script>
export default {

  watch : {
    $route(obj){
      console.log('id:',obj.params.id);
    }
  }
}
</script>

2. 路由对象 - $route

  • 一个路由对象 (route object) 表示当前激活的路由的状态信息,包含了当前 URL 解析得到的信息

  • 一个哈希值路径 ==> 一个路由对象

  • $route.path

    • 类型: string

    • 字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"

    • # 后面?前面的内容

  • $route.params

    • 类型: Object

    • url参数对象

    • 一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。

  • $route.query

    • 类型: Object

    • 查询参数对象

    • 一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 $route.query.user == 1,如果没有查询参数,则是个空对象。


# 演示 :
<router-link to="/detail/4?age=21">detail</router-link>
{ path: '/detail/:id?', component: detail }

在组件内 created打印 this.$route
> params : {id:'4'}
> query : {age : 21}
> path : '/detail/4'

3. 嵌套路由 (子路由)

3.1 模板结构


<style>
 .home {
    200px;
   height: 200px;
   border: 4px solid lime;
}
 .list {
    200px;
   height: 200px;
   border: 4px solid red;
}
 .one,
 .two {
   border: 3px solid #000;
    100px;
   height: 100px;
}
</style>

const home = {
template: `<div class='home'>home <router-view /> </div>`,
}
const list = {
template: `<div class='list'>list</div>`,
}
const one = {
template: `<div class='one'>one</div>`,
}
const two = {
template: `<div class='two'>two</div>`,
}
  • parent 的内部 添加 : <router-view> </router-view>

  • 规则里添加 children

  • 那么访问就应该访问#/home/one才可以访问子组件


const router = new VueRouter({
       // 2. 规则
       routes: [
        {
           path: '/home',
           component: home,
           children: [
            { path: '/one', component: one },
            { path: '/two', component: two },
          ],
        },
        { path: '/list', component: list },
      ],
    })

4. 编程式导航

跳转的三种方式

1-声明式导航 通过导航组件跳转

2-编程式导航 通过js代码来实现跳转

  • 解释


# push() 跳转 保留历史记录 (可返回)
go(1)
# back() 返回
go(-1)
# replace() 跳转 不保留历史记录 (不可返回)
  • 代码


// one组件
 methods: {
   jump() {
     // this.$router.push('/two')
     // this.$router.go(1)
     this.$router.replace('/two')
  },
},
}
// two组件
 methods: {
   back() {
     // this.$router.back()
     this.$router.go(-1)
  },
},

5. 命名路由


有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。
  • 场景1 : 重定向

  • 场景2 : 声明式导航链接跳转


//1
<router-link to='/home'>123</router-link>
//2
<router-link :to='{ name : "home" }'>123</router-link>
  • 场景3 : 编程时导航跳转传参

6. 重定向

  • 方式1 : 路径


routes: [
  { path: '/', redirect: '/home'}
]
  • 方式2 : 对象


routes: [
  { path: '/', redirect: { name: 'home' }}
]

7. 编程时跳转页面传参


// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

原文地址:https://www.cnblogs.com/zmztya/p/14447191.html