vue-router学习分享

1、vue-router是什么

这里的路由不是平时说的硬件路由器,这里的路由就是SPA(单页应用)的路径管理器。vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适用于构建单页面应用。

vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。

传统的页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。路由模块的本质 就是建立起url和页面之间的映射关系

至于我们为啥不能用a标签,这是因为用Vue做的都是单页应用(当你的项目准备打包时,运行npm run build时,就会生成dist文件夹,这里面只有静态资源和一个index.html页面),所以你写的标签是不起作用的,你必须使用vue-router来进行管理。

2、vue-router实现原理

SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是: 更新视图而不重新请求页面;vue-router在实现单页面前端路由时,提供了两种方式:Hash模式和History模式;根据mode参数来决定采用哪一种方式。

2.1、Hash模式:

vue-router默认hash模式:使用URL的hash来模拟一个完整的URL,于是当URL改变时,页面不会重新加载。hash(#)是URL的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载页面。也就是说hash出现在URL中,但不会被包含在http请求中,对后端完全没有影响,因此改变hash不会重新加载页面。
在这里插入图片描述
同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置。所以说Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据。hash 模式的原理是 onhashchange 事件(监测hash值变化,在当前 URL 的锚部分发生修改时触发),可以在 window 对象上监听这个事件

2.2、History模式:

由于hash模式会在url中自带#,如果不想要很丑的hash,我们可以用路由的history模式,只需要在配置路由规则时,加入mode: ‘history’,这种模式充分利用了html5 history interface 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器记录栈,在当前已有的 back、forward、go 基础之上,它们提供了对历史记录修改的功能。只是当它们执行修改时,虽然改变了当前的 URL ,但浏览器不会立即向后端发送请求
在这里插入图片描述
不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。

所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

 export const routes = [ 
  {path: "/", name: "homeLink", component:Home}
  {path: "/register", name: "registerLink", component: Register},
  {path: "/login", name: "loginLink", component: Login},
  {path: "*", redirect: "/"}]

此处就设置如果URL输入错误或者是URL 匹配不到任何静态资源,就自动跳到到Home页面。

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

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

4、vue-router使用方法

  • 1:下载 npm i vue-router -S
  • 2:在main.js中引入 import VueRouter from 'vue-router';
  • 3:安装插件Vue.use(VueRouter);
  • 4:创建路由对象并配置路由规则 let router = new VueRouter({routes:[{path:'/home',component:Home}]});
  • 5:将其路由对象传递给Vue的实例,options中加入 router:router
  • 6:在app.vue中留坑 <router-view></router-view>

具体代码:
在这里插入图片描述
app.vue中“留坑“:
在这里插入图片描述

5、重定向和别名

5.1、重定向

“重定向”的意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b

重定向也是通过 routes 配置来完成,从/a重定向到/b

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

重定向的目标也可以是一个命名的路由:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: { name: 'foo' }}
  ]
})

甚至是一个方法,动态返回重定向目标:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
    }}
  ]
})

注意导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。在上面这个例子中,为 /a 路由添加一个 beforeEnter 守卫并不会有任何效果。

5.2、别名

别名:/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]
})

“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。

6、vue-router参数传递

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

6.1、用name传递参数

在路由文件router/index.js里面配置name属性
在这里插入图片描述
在模板里面用$router.name来接收

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

基本语法:

<router-link :to="{name: 'aa', params: {key: value}}"></router-link>

router/index.js

{path: '/aa', name: 'aa', compoent: aa}

在模板里面用$router.params.key来接收

6.3、利用url传递参数----在配置文件里以冒号的形式设置参数。

在router/index.js里面配置

{
    path:'/params/:newsId/:newsTitle',
    component:Params
}

7、命名视图

7.1、vue-router配置子路由(二级路由)

在原有的路由配置下加入children字段。

{
            path: '/a',
            name: 'pageA',
            component: pageA,
            children: [
                {
                    path: '/c',
                    name: 'pageC',
                    component: pageB
                },
                {
                    path: '/d',
                    name: 'pageD',
                    component: pageUnit
                }
            ]
        }

在这里插入图片描述

7.2、单页面多路由区域操作

在一个页面里我们有两个以上<router-view>区域,我们通过配置路由的js文件,来操作这些区域的内容

  • 1、App.vue文件,在<router-view>下面新写了两行<router-view>标签
    在这里插入图片描述

  • 2、需要在路由里配置components字段里进行

   {
      path: '/',
       name: '/',
       components: {
           default: pageUnit,
           pageA: pageA, // 显示A组件内容
           pageB: pageB // 显示B组件内容
       }
   }

8、$route$router的区别

在这里插入图片描述

8.1、$route

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

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

  • $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:当前路径名字

8.2、$router

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

$router常见跳转方法:

this.$router.go(-1)//跳转到上一次浏览的页面
this.$router.replace('/menu')//指定跳转的地址
this.$router.replace({name:'menuLink'})//指定跳转路由的名字下
this.$router.push('/menu')//通过push进行跳转
this.$router.push({name:'menuLink'})//通过push进行跳转路由的名字下

$router.push$router.replace的区别:

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

9、404页面设置

用户会经常输错页面,当用户输错页面时,我们希望给他一个友好的提示页面,这个页面就是我们常说的404页面。vur-router也为我们提供了这样的机制。

  • 1、设置我们的路由配置文件(router/index.js)

    {
       path:'*',
       component:Error
    }
    

    这里的path:’*'就是输入地址不匹配时,自动显示出Error.vue的文件内容

  • 2、在/src/components/文件夹下新建一个Error.vue的文件。简单输入一些有关错误页面的内容。

    <template>
        <div>
            <h2>{{ msg }}</h2>
        </div>
    </template>
    <script>
    export default {
      data () {
        return {
          msg: 'Error:404'
        }
      }
    }
    </script>
    

    此时我们随意输入一个错误的地址时,便会自动跳转到404页面。

进阶

1、导航守卫

每个守卫方法接收三个参数:

  • to:Route:即将要进入的目标路由对象
  • from:Route :当前导航正要离开的路由
  • next:function:一定要调用这个方法来resolve这个钩子。执行效果依赖next方法的调用参数。
    • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
    • next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
    • next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: truename: 'home' 之类的选项以及任何用在 router-linkto proprouter.push 中的选项。

1.1、全局前置守卫

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中

router.beforeEach((to, from, next) => {
    console.log('这里打印的是即将要进入的页面信息');
    console.log(to);
    console.log('这里打印的是即将要离开的页面信息');
    console.log(from);
    next();
})

在这里插入图片描述
在这里插入图片描述

1.2、全局后置钩子

router.afterEach((to, from) => {
    console.log('这里打印的是即将要进入的页面信息11 afterEach');
    console.log(to);
    console.log('这里打印的是即将要离开的页面信息11');
    console.log(from);
});

在这里插入图片描述

1.3、路由独享的守卫

在这里插入图片描述
在这里插入图片描述
这些守卫与全局前置守卫的方法参数是一样的。

1.4、组件内的守卫

在这里插入图片描述
在这里插入图片描述

完整的导航接卸流程

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

2、路由元信息

  • 1、路由定义

    {
        path: '/a',
        name: 'pageA',
        component: pageA,
        meta: {requiresAuth: true},
    }
    

    这里的mate字段就是路由元信息字段,requiresAuth是自己起的字段名称,我们可以用这个字段来标记路由信息是否需要检测。(true表示需要检测、false表示不需要检测)

  • 2、js代码

    router.beforeEach((to, from, next) => {
        //这里meta字段的名称要与上面route里面保持一致
        if (to.matched.some(record => record.meta.requiresAuth)) { 
            // this route requires requiresAuth, check if logged in
            // if not, redirect to login page.
            if (!this.loggedIn()) { // 自己的判断条件
                next({
                    path: '/', // 重定向后的路由
                    query: {redirect: to.fullPath} // 登录成功之后可以根据query中的内容跳转回原来的路由(页面)
                });
            } else {
                next();
            }
        } else {
            next() // 确保一定要调用 next()
        }
    });
    

3、过渡效果

在这里插入图片描述
效果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值