我所理解的VUE路由管理

Web应用在现代的互联网应用中占据非常重要的地位,大屏电脑、笔记本、平板、手机等设备的界面显示有统一使用web界面的趋式,设计一套界面,适应于多种设备已成为一种客观现实,,web前端已经从简单的网站开发成长为专用前端技术,有简单、适用范围广等特点.。

一 WEB应用简介

WEB的开发与应用可以分为单页面应用(SPA  SinglePage Application)和多页面应用(MPA  MultiPage Application),多页面应用是传统的web应用程序,每个页面都是独立的HTML文件,每次页面刷新都会加载整个页面。单页面应用基于现代web技术,它使用一个javascript在一个单独的页面上构建整个应用程序,实现局部刷新、数据异步加载和响应式布局等特性。

多页面应用的优点:

  1. 有利于SEO优化:每个页面都有自己的URL地址,可以更容易地针对每个页面进行SEO优化。
  2. 安全性更高:多页面应用程序使用后端进行数据处理和业务逻辑处理,可以更好地防止XSS和CSRF等攻击。
  3. 首次加载时间优化:由于每个页面只需要加载自己的资源文件和数据,所以首次加载时间相对较短。

多页面应用的缺点:

  1. 用户体验较差:由于页面刷新可能需要花费较长的时间,用户体验可能相对较差。
  2. 操作复杂:当需要在不同页面之间进行切换时,需要重新加载整个页面,用户操作可能较为繁琐。
  3. 维护复杂:每个页面都是单独的HTML文件,所以多页面应用可能比较复杂,不易于维护

单页面应用优点:

  1. 用户体验良好:SPA具有快速和流畅的页面切换和局部更新效果,可以提供更好的用户交互和体验。
  2. 高效性能:SPA不需要每次刷新页面,只需要更新局部,可以大大减少页面切换时间和服务器负载。
  3. 易于维护:由于SPA使用单一页面,使得应用程序结构更加简单,易于维护。

单页面应用的缺点:

  1. 首次加载时间长:由于SPA需要加载单个页面,所以在首次加载时,需要加载所有的JavaScript、CSS和HTML文件,可能需要很长时间才能完成。
  2. SEO不友好:由于只有一个HTML文件,搜索引擎很难找到页面的内容和关键字,对SEO有一定的影响。
  3. 安全问题:由于SPA需要在前端处理大部分业务逻辑和数据处理,因此容易受到XSS和CSRF等攻击。

综上所述,SPA更适合需要快速响应和更好用户体验要求的应用程序,而MPA则适用于需要更好的SEO和安全性的应用程序。

在单页面应用中,前后端分离成为主流,前端页面完全变成了组件化,不同的页面就是不同的组件,页面的切换就是组件的切换。页面切换的时候不需要再通过HTTP请求,直接JS解析URL地址,然后找到对应的组件进行渲染、不仅页面无刷新,甚至页面跳转也可以无刷新。整个项目只有一个HTML文件,不同视图(组件的模板)的内容都是在同一个页面中渲染的。当用户切换页面时,页面之间的跳转都是在浏览器端完成的,前端路由(借鉴后端路由概念,传统MVC架构的WEB开发在后台设置路由规则,当用户发送请求时,后台根据设定的路由规则将数据渲染到模板中,并将模板返回给用户)随之应运而生。Vue Router是Vue的官方路由,是Vue 生态中前端路由的解决方案,与Vue核心深度集成,可以在SPA中创建一个无限的路由组合。

二 Vue Router的实现原理

单页面应用之所以做到页面跳转时不刷新,其核心在于以下两点:

1、改变URL,页面不刷新。

2、改变URL,可以监听到路由的变化并能够做出一些处理

基于浏览器的核心实现分为Hash和HTML5两种历史模式:

Hash模式:

Hash模式是Vue Router利用浏览器的特性,Hash是URL中hash(#)及后面的哪部分(如http://example.com/#user中的#user),常用作锚点在页面内进行导航,Hash值的变化 并不会导致浏览器向服务器发出请求,浏览不发出请求,也就不会刷新页面,所以也不需要在服务器层面上进行任何特殊处理(因此它并不利于SEO),之后通过主动跳转或者监听hashchange事件监听URL的变化即可实现我们的目标。因为这种特性,使WEB应用程序在没有主机的情况下也能正常跳转。

HTML5模式

随着HTML5的发展,浏览器的不断更新,HTML5 History方法变得强大,它提供了pushState和replaceState两个方法,这两个方法改变URL的path部分不会引起页面刷新,同时它提供类似hashchange事件的popstate事件,但又区别于hashchange事件:通过浏览器前进、后退改变URL时会触发popstate事件,而通过pushState/replaceState或<a>标签改变URL不会触发popstate事件。

Vue Router的HTML5模式是利用HTML5的HistoryApi来控制状态(通过拦截pushState/replaceState的调用和<a>标签的单击事件来检测URL的变化),当使用这种历史模式时,URL没有像Hash历史模式的"#",会看起来很“正常”,例如https://example.com/user/id。

三 安装引入

1、直接引入

直接引入是在HTML中通过script标签直接引入编译好的JS文件,这个文件可以 是官方提供的CDN 地址(https://unpkg.com/vue-router@4),或者从CDN地址下载后存放到指定位置的地址,如下:

<script src="https://unpkg.com/vue-router@4"></script>

注意: 通过使用script标签引入Vue Router需要在引入Vue文件之后引入。

这种通过script标签引入VueRouter文件的方式将在全局暴露Vue Router对象,可以通过Vue Router访问其下所有的属性和方法。

2、使用npm安装

通过npm命令行直接安装Vue Router,如下:

npm install vue-router@4

npm install vue-router@next

注意:可以在准备好的Vue 3工程中使用此方法安装Vue Router,实际开发过程中,可以添加--save或--S参数将依赖保存到package.json文件中。

3、Vue CLI安装

在使用Vue CLI创建好的Vue项目中以项目插件的形式添加Vfue Router,通过Vue CLI安装Vue Router,如下:

vue add router

注意:1、根据需要选择是否使用history路由模式

 或者可以在创建一个全新项目时,根据提示选择Router直接安装VueRouter,操作步骤如下:

vue create  <project-name>

注意:1、选择 Manually select features(手动选择特性)

           2、使用键盘上下键,在Router按下空格键,选中 VueRouter

           3、按回车键后,选择Vue版本号,选择3.x后按回车键确定.

           4、根据需要选择是否使用history路由模式.

           6、根据需要选择是否保存预设以供将来项目使用.

四 使用Vue Router

1. 创建页面文件

VueRouter的基本作用就是将每个路由映射到对应的组件,并通过修改路由进行组件间的切换。假设现在有两个页面路由,分别对应Home和About 两个页面,在src/components文件夹下新建两个Vue文件.

Home.vue文件

<template>
<h1>我是Home</h1>
</template>
<script>
export default {

};
</script>

About.vue文件

<template>
<h1>我是About</h1>
</template>
<script>
export default {

};
</script>

2. 添加路由容器

路由容器router-view用于展示不同url对应的页面内容,修改App.vue文件<template></template>内容如下:

<template>
<p>
<router-link to="/home">Home</router-link>
<router-link to="/about">About</router-link>
</p>
<router-view></router-view>
</template>

3. 定义路由

首先,在main.js引入组件Home和About组件:

import Home from "./components/home.vue"
import About from "./components/About.vue"

将路由映射到组件中。定义一个路由数组 ,根据Vue Router路由配置path和components,并创建路由实例,传入路由配置,通过createWebHashHistory方法设置成Hash模式或通过createWebHistory方法设置成HTML5模式,如下:

const routes=[
    {
      path: '/',
      component: 'Home',
    },
    {
      path: '/about',
      component: 'About',
    }
]
//创建路由实例,把定义的路由挂载到路由实例中
const router=createRouter({
         history: createWebHashHistory(),
         routes: routes
})

4. 使用路由

createApp(App)
        .use(router) //挂载到根实例
        .mount('#app')

五 页面跳转

1、router-link标签跳转

router-link标签的底层逻辑是创建一个a标签,通过a链接进行跳转,router-link跳转分为带参数和不带参数跳转,用法如下:

不带参数     

<router-link to="/home“>Home</router-link>
<router-link :to={name:"home“}>Home</router-link>
<router-link to={path: "/home“}>Home</router-link>

带参数:

<router-link to={name: "home“,params: {id:1}}>Home</router-link>
<router-link to={path: "/home“,query :{id:1}}>Home</router-link>

2、JS脚本跳转

通过JS脚本实现跳转,即借助router实例方法(push,replace,go 等),可分为带参数和不带参数跳转。下面以push方法为例,可替换为replace,go等,在vue实例中,可以通过$router访问路由实例(调用this.$router.push),使用方法如下:

//字符串路径
this.$router.push('/users')
//带有路径的对象
this.$router.push({path: '/user'})
//命名的路由,加上参数,让路由建立url
this.$router.push({name: 'user',params: {username: 'guest'}})
//带查询参数,结果是/register?plan=private
this.$router.push({path: '/register',query:{plan: 'private'}})
//带hash,结果是/about#team
this.$router.push({path: '/about'},hash: '#team')

六  路由传参

路由参数方式包含两大类: 声明式导航router-link和编程式导航,传参方式分为字符串、对象两种。

1、字符串

字符串方工是直接将路由地址以字符串的方式来跳转,方式简单,但不能传递参数,如下:

//字符串路径
//router-link方式
<router-link to="/home">Home</router-link>
//编程式
router.push("/home")

2、对象

使用对象传递参数,可以分为命名路由和查询参数两种方式。

命名路由

命名路由是在注册路由的地方通过name给路由命名,如下:

const routes=[{
        name: "home", //命名路由
        path: '/',
        component: Home
        },
        {
          name: 'about',
          path: '/about',
          component: About
        }
]

传递参数时通过params传递,如下:

//router-link方式
<router-link :to="{name: 'home',params: { id: 1}}">Home</router-link>
//编程式
router.push({name: 'home',params: { id: 1}})

此种传递方式在组件中,选项式API通过this.$route.params获取,组合式API在setup中通过useRoute().params获取,useRoute方法需要先从vue-router中导入,即import { useRoute}  from 'vue-router'。例如上例中获取id,则选项式API获取方式为this.$route.params.id,组合式API获取方式为useRoute().params.id。

查询参数

查询参数是在路由地址后面带上参数,和传统参数一致,传递参数使用query,而且必须配合path来传递参数而不能用 name,目标页面接收传递的参数使用query,如下:

//router-link方式
<router-link :to="{name: 'home',query: { id: 1}}">Home</router-link>
//编程式
router.push({name: 'home',query: { id: 1}})

此种传递方式在组件中,选项式API通过this.$route.query获取,组合式API在setup中通过useRoute().query获取,useRoute方法需要先从vue-router中导入,即import { useRoute}  from 'vue-router'。例如上例中获取id,则选项式API获取方式为this.$route.query.id,组合式API获取方式为useRoute().query.id。

七 命名视图

同时展示多个视图,而不嵌套展示,如创建布局有侧导航和主内容两个视图,可以通过命名视图实现展示。如下单页面多路由基础示例:

假定有两个组件Home和About,分为上下两个不同的区域,修改App.vuer的<template></template>,如下:

<template>
<div>
<router-view name="top"></router-view>
<router-view></router-view>
</div>
</template>

加入一个命名为top的<router-view>区域,然后创建两个不同的头部组件,放在src/components文件夹下:

//头部组件Header1.vue
<template>
<h1>我是Home头部</h1>
<router-link to='/about'>go to about</router-view>  
</template>


//头部组件Header2.vue
<template>
<h1>我是About头部</h1>
<button @click='goHome'>从头部返回Home</button>
</template>
<script>
export default {
    methods: {
       goHome(){
           this.$router.push('/')
       }
    }
}
</script>

最后,需要在main.js中引入并使用,修改routes的定义,如下:

const routes=[
       { name: 'home',
         path: '/',
         components: {
             default: Home,
             top: Header1
             }
        },
        { name: 'about',
          path: '/about',
          components: {
             default: About,
             top: Header2
          }     
        }
    ]

注意:原来只有一个router-view时,定义routes时component为单数形式,现大定义多个视图,需要做成复数形式components。

最后,页面刷新后的结果如图所示(默认展示home页面内容)。

单击home页面的头部区域链接,可以直接跳转about页面,在 about页面可以操作头部和默认区域按钮,跳回home页面,如图所示:

八 配置子路由

一个应用是由有很多个页面组件组合而成,页面与页面之间可能存在嵌套关系。假设有这样一个要求,在用户中心界面包含用户个人信息和用户设置等功能,这时用户中心作为父级,个人信息和用户设置内容区域是二级,这种情况就可以通过配置子路由的方式切换个信信息页面和用户设置页面。嵌套路由如下:

修改main.js文件,引入user页面模板,加入user 的子集路由配置,在Vue-Router的参数中使用children配置,代码如下:

const routes=[
           {
             path: '/',
             name: 'home',
             component: Home
            },
            {
             path: '/user',
             name: 'userCenter',
             component: UserCenter,
             redirect: '/user/profile',
             children: [
                  {
                     name: 'profile',
                     path: 'profile',
                     component: UserProfile
                  },
                   {
                     name: 'settings',
                     path: 'settings',
                     component: UserSettings
                  }
               ]
             }
]

const router=createRouter({
                  history: createWebHashHistory(),
                  routes: routes
})

从以上的代码可以看到,子路由children配置是一个数组,每一个数组项对应一个组件component,它的配置与一级路由具有相同的属性,可以设置路径path,命名路由name及定义访问的component等属性。如果还有更多级的嵌套,就可以在层层父级页面添加路由容器,并在路由文件中对应的父级下添加children 子级路由配置。

九 路由导航守卫

导航守卫也叫路由守卫,主要作用是在进行路由跳转时决定通过此次跳转或拒绝此次跳转。可以在全局注册导航守卫,也可以在单个路由中注册,即有多种方式植入路由导航过程,可分为 全局导航守卫、路由独享导航守卫、组件内导航守卫。守卫也可分为两大类,分别是前置守卫和后置守卫,分别表示在拦截路由跳转前的操作和路由跳转后的操作。  

前置守卫包括:

       全局的前置守卫: beforeEach,beforeResolve

       路由独享的守卫: beforeEnter

      组件内的守卫: beforeRouterEnter、beforeRouterUpdate、beforeRouterLeave

后置守卫包括:

         全局后置守卫: afterEach

全局前置守卫

全局前置守卫用于在路由配置生效(路由发生改变)之前进行一些动作,在beforeEach()守卫方法中传入一个参数,此参数为一个回调函数,此函数中传入三个参数,分别是to、from 、next.

 to 表示即将进入的目标路由对象

from 表示当前导航正要离开的路由

next表示继续执行则必须调用next方法

使用全局前置守卫在用户未能验证身份时重新定向到/login页面。代码如下:

router.beforeEach((to,from,next)=>{
            if(to.name!=="Login" && ! isAuthenticated)
                next({ name: 'Login'})
            else next()
           })

路由导航跳转的全过程

1。导航被触发,可以通过router-link组件触发,也可以通过router.push或直接改变url触发。

2、在将要失活的组件中调用beforeRouterLeave守卫函数

3、调用全局注册的beforeEach守卫函数

4、如果当前使用的组件没有变化,调用组件内的beforeRouterUpdate守卫

5、调用在定义路由时配置的beforeEnter守卫函数

6、解析异步路由组件

7、在被激活的组件中调用beforeRouteEnter守卫

8、导航被确认

9、调用全局注册的afterEach守卫

10、触发DOM更新,页面进行更新

11、调用组件的beforeRouteEnter函数汇总next参数注册的回调函数

十  动态路由

在Vue-Router中有两种路由形式,静态路由和动态路由,静态路由需要先在main.js中完成路由的配置,再在项目中使用。动态路由可以在运行过程中动态添加或删除路由。动态操作路由的方法主要有两个:addRoute和removeRoute,分别是添加一条路由和删除一条路由。示例代码如下:

this.$router.addRoute({ path : '/demo2',component: Demo2 })

在下面几种场景下触发路由的删除,当使用addRoute方法添加了重名路由时,旧的会被删除。调用addRoute方法时,会返回一个删除回调,通过此删除回调直接删除所添加的路由。代码如下:

let call=this.$router.addRoute({
                path: '/demo2',
                component: Demo2,
                name: 'Demo2'
});

//直接移除此路由
call();

另外,对于已经命名的路由,也可以通过名称来对路由进行删除,代码如下:

this.$router.addRoute({
            path: '/demo2',
            component:Demo2,
            name: "Demo2"
});
this.$router.removeRoute("Demo2")

注意: 1. 路由被删除时,其所有的别名和子路由也会同步被删除。

            2. 提供了获取现有路由的方法,hasRouter方法用来检查已经注册的路由中是否包含某个路由,getRouters方法用来获取包含所有路由的列表。

十一 设置404页面

一个友好的错误页面比没有错误页面给用户带来更以的体验,另外也可以通过错误页面引导 用户回到正常的网页中去。由于站点存在的路径有限,不存在的路径却是无限,因而需要匹配一系列地址到统一的错误页面去,这时可以通过path配置正则表达式来将站点内满足匹配规则的页面指向对应的页面组件,以达到根据规则跳转的效果。

具体实施时,在routes后新增一条匹配规则,主要代码如下:

const routes=[
       ...
       {

         path: '/:pathMatch(.*)*',
         name: 'NotFound',
         component: NotFound
       }
]

以上代码路径参数是pathMatch,括号内的正则表达式匹配所有路径(.*),这些匹配到路径将会存入$route的pathMatch参数中,可以通过route.params.pathMatch读取。运行项目,随便访问一个地址,例如: ‘/user/aaa’,可以跳转到了404页面。

路由技术在实际项目开发中应用广泛,随着网页应用的功能越来越强大,前端代码也越来越复杂,如何高效清晰地根据业务模块组织代码变得十分重要,路由就是一种非常优秀的页面组织方式,通过路由可以将页面按照组件的方式进行拆分,组件内只关注内部的业务逻辑,组件间通过路由来进行交互和跳转。

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值