《路由 vue-­router》

209 阅读5分钟

router 路由是什么? 分发请求

维基百科解释:路由routing)就是通过互联的网络信息从源地址传输到目的地址的活动。

路由引导分开送往,经过一些中间的节点后,到它们最后的目的地。

作成硬件的话,则称为路由器

路由通常根据路由表——一个存储到各个目的地的最佳路径的表——来引导分组转送。

VueRouter是什么

是Vue.js的官方路由,它与Vue.js核心深度集成,让Vue.js构建单页面应用变得轻而易举。

1、vue-router路由基本加载

vue-router详情点击

router-link , router-view , 嵌套路由 , Hash模式 和 History模式 、 导航守卫 、 懒加载

2、Hash模式 和 History模式 有 什么区别?

Hash模式:hash(#)

vue-router 默认为 hash 模式,使用 URL 的 Hash 来模拟一个完整的URL 。当URL改变时,页面不会重新加载。hash(#)是 URL 的锚点,代表的是网页中的一个位置,改变#后的部分,游览器只会滚到相应的位置,不会重新加载网页。换言之,hash 会出现在 URL 中 ,不会出现在 http 请求中

http://www.xxx.com/#/login

同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;所以说Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据。hash 模式的原理是 onhashchange 事件(监测hash值变化),可以在 window 对象上监听这个事件

优点:完全前端路由,只改变#后面值,无刷新。

缺点:不会出现在http请求中,服务器接收不到hash,SEO不友好。

解决方案:google hash seo ,需要服务器做些配置。需要在#后加!,能够让谷歌识别,是不同的页面。但还是不能和以前的内容相比。

可以用History模式

History模式:

后端将所有前端路由都渲染同一页面。

在配置路由规则时,加入"mode: 'history'",这种模式充分利用了html5 history interface 中新增的 pushState()replaceState() 方法。 通过这两个 API 可以改变 URL 地址,但是不会向后端发送请求。

//main.js文件中
const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,需要把所有路由都重定向到根页面。

优点:在同源的情况下,实现了前端完全自由,stateObject可以是任何数据类型,URL可以是相对路径也可以是绝对路径。

缺点:如果后端没有做对应的路由,在刷新时会出现404。IE8以下不支持。

2.2、memory 模式

memory模式代码: codesandbox.io/s/936269l69…

该模式就是将路由存在一个对象里,在URL里看不到对应的路径,适用于手机端,但使用很少。

3、使用路由模块来实现页面跳转的方式

  • 方式1:直接修改地址栏
  • 方式2:this.$router.push(‘路由地址’)
  • 方式3:<router-link to="路由地址"></router-link>

4、使用

4.1、安装

我的cli用的vue2,我装的@3.5.2这个版本,官网是@4,我装这个报错。

npm

npm install vue-router@3.5.2 --save

yarn

yarn add vue-router@3.5.2

成功后package.json会生成vue-router配置

屏幕截图 2022-07-31 173834.png

4.2、 引用


import router from 'vue-router' 
Vue.use(router)

4.3、配置路由文件,并在vue实例中注入

在router中配置

import HelloWorld from '../components/HelloWorld.vue'
export default new router({  //创建路由对象
  routes: [
   {
      path: '/helloworld',//指定要跳转的路径
      component: HelloWorld,//指定要跳转的组件
   }])

需要在main.js中引入router文件

import rt from './router/index'
new Vue({
  render: h => h(App),
  router:rt,

}).$mount('#app')

4.4、 确定视图加载的位置

<router-view></router-view>

5、vue-router路由的跳转

在components文件夹创建一个HelloChina.js组件

在components文件夹创建一个list.js组件 通过router-link点击链接会跳转

<template>
    <ul>
        <li>
            <router-link to="/helloworld">HELLO WORLD</router-link>
        </li>
        <li>
            <router-link to="hellochina">HELLO CHINA</router-link>
        </li>
    </ul>
</template>

<script>
export default {
    name: 'hello-list'
}
</script>

<style scoped>
li {
    margin: 3px;
}
</style>

这样我们components文件夹有3个文件

在router文件夹里创建一个index.js的路由

import router from 'vue-router' 
import Vue from 'vue'

import HelloWorld from '../components/HelloWorld.vue'
import HelloChina from '../components/HelloChina.vue'

Vue.use(router)

export default new router({  //创建路由对象
  routes: [
    {
       path: '/helloworld',//指定要跳转的路径
       component: HelloWorld,//指定要跳转的组件
    },
    {
    path: '/hellochina',//指定要跳转的路径
    component: HelloChina,//指定要跳转的组件
    }
  ]
})
  

通过路由的引导,我们在list.js组件才会正确跳转目的地。

6、vue-router路由参数的传递

声明式的导航<router-link :to="...">和编程式的导航router.push(...)都可以传参

主要介绍前者的传参方法

1.必须在路由内加入路由的name ,才能跳转到当前页面
2.必须在path后加/: +传递的参数 
3. 传递参数和接收参数看下边代码

router-link里面传的参数,必须在index路由path里面定义。 然后在相应的组件里接收参数 这是第一种写法

通过<router-link> 标签中的to传参

routes: [
    {
       name:'helloworld',
       path: '/helloworld/:worldmsg',//指定要跳转的路径
       component: HelloWorld,//指定要跳转的组件
    },
    {
    name:'hellochina',
    path: '/hellochina/:chinamsg:',//指定要跳转的路径
    component: HelloChina,//指定要跳转的组件
    }
  ]
<ul>
        <li>
            <router-link :to="{ name: 'helloworld', params: { worldmsg: '只有一个地世界' } }">HELLO WORLD</router-link>
        </li>
        <li>
            <router-link :to="{ name: 'hellochina', params: { chinamsg: '只有一个中国' } }">HELLO CHINA</router-link>
        </li>
    </ul>
<h3>{{ $route.params.worldmsg }}</h3>

还有第二种方法不常用,使用path来匹配路由,然后通过query来传递参数

    <router-link
    :to="{path:'/hellochina',query:{chinamsg:只有一个中国}}">
    HELLO CHINA
    </router>

方式:===/helloworld?name=xx&count=xxx

函数模式:

创建一个函数返回props。这样你便可以将参数转换成另一种类型,将静态值域基于路由的值结合等等。

const router = new VueRouter({
    router:[
        {path:'/search',component:searchUser,props:(router)=>({
                query:route.query.q
        })}
    ]
})

7、$route 和 $router 的区别

$route 是“路由信息对象”,包括 path,params,hash,query,fullPath,matched,name 等路由信息参数。

$route.path 字符串,对应当前路由的路径,总是解析为绝对路径,如 "/order"。

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

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

$route.hash 当前路由的 hash 值 (不带 #) ,如果没有 hash 值,则为空字符串。

$route.fullPath 完成解析后的 URL,包含查询参数和 hash 的完整路径。

$route.matched 数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。

$route.name 当前路径名字

$router 是“路由实例”对象,即使用 new VueRouter创建的实例,包括了路由的跳转方法,钩子函数等。

$router常见跳转方法:

<button @click="goToMenu" class="btn btn-success">Let's order!</button>
.....
<script>
  export default{
    methods:{
      goToMenu(){
        this.$router.go(-1)//跳转到上一次浏览的页面
        this.$router.replace('/menu')//指定跳转的地址
        this.$router.replace({name:'menuLink'})//指定跳转路由的名字下
        this.$router.push('/menu')//通过push进行跳转
        this.$router.push({name:'menuLink'})//通过push进行跳转路由的名字下
      }
    }
  }
</script>
复制代码

$router.push$router.replace的区别

  • 使用push方法的跳转会向 history 栈添加一个新的记录,当我们点击浏览器的返回按钮时可以看到之前的页面。
  • 使用replace方法不会向 history 添加新记录,而是替换掉当前的 history 记录,即当replace跳转到的网页后,‘后退’按钮不能查看之前的页面。

参考

从头开始学习vue-router - 掘金 (juejin.cn)