Vue Router路由学习

Vue Router

  • 1、什么是路由?
  • 2、vue router实现原理
    • 2.1、hash模式
    • 2.2、history模式
  • 3、路由基础
    • 3.1、路由列表
    • 3.2、路由标签
  • 4、动态路由匹配
    • 4.1、动态路由路径
    • 4.2、响应(监听)动态路由参数的变化
    • 4.3、捕获所有路径(路由)
  • 5、嵌套路由
  • 6、编程式导航
    • 6.1、push
    • 6.2、replace
    • 6.3、go
  • 7、路由配置
    • 7.1、命名路由
    • 7.2、重定向redirect
    • 7.3、别名alias
    • 7.7、其他
  • 8、路由传参
    • 8.1、query
    • 8.2、params
    • 8.3、props
    • 8.4、query 和 params的区别
  • 9、导航守卫
    • 9.1、全局前置守卫
    • 9.2、路由独享守卫
  • 10、路由懒加载
    • 10.1、vue异步组件实现懒加载
    • 10.2、ES6 提出的import方法(最常用,推荐使用)
    • 10.3、webpack提供的require.ensure()实现懒加载
  • 11、vue2中动态添加路由router.addRoute

1、什么是路由?

根据用户给出的url地址,导航到不同组件中;

2、vue router实现原理

SPA:单一页面应用程序,只有一个完整的页面,它在加载页面时,不会加载整个界面,而是只更新某个指定的容器中的内容。单页面应用(SPA)的核心之一是:更新视图而不是更新请求页面。Vue Router在实现单页面前端路由时,提供了两种方式:hash模式和history模式,默认使用的是hash模式。

2.1、hash模式

  • url hash就是类似于:localhost:8080/#/login

这种#后面hsah值的变化,并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。而每次hash值的变化,还会触发hashchange事件,通过这个时间我们就可以知道hash值发生了哪些变化。我们便可以监听hashchange来实现更新页面部分的内容的操作。因此改变hash不会重新加载页面

    function matchAndUpdate(){
      
	}
window.addEventListener("hashchange",matchAndUpdate)

2.2、history模式

因为HTML5标准发布,多了两个API, pushState 和replaceState,通过这两个API可以改变url地址且不会发送请求。同时还有popstate事件。通过这些就能用另一种方式来实现前端路由了,但原理都是跟hash实现相同的。用了HTML5的实现,单页路由的url就不会多出一个#,变得更加美观。但因为没有#号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。为了避免出现这种情况,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。

    function matchAndUpdate(){
      
	}
window.addEventListener("popstate",matchAndUpdate)

3、路由基础

3.1、路由列表

const router = new VueRouter({
	路由列表:是一个数组
    routes:[
    	单个路由
    	path:表示路由路径字符串,在path中需要/开头,目的使全局路由对象能够监听到某个用户请求的路径;
    	component:组件,如果path与用户访问的路径匹配,则去查找相应的组件,让组件渲染页面

		{
		path:/login,
		component:Login
		}
	]
})

3.2、路由标签

<router-link>标签,进行路由导航,它会被Vue解析为一个超链接;
to属性:配置路由路径;
<router-link to="/login">登录</router-link>(声明式导航)

通过router-link标签导航之后,组件如何渲染到页面中?
<router-view/>:渲染某个路由路径对应的组件,称为路由出口

4、动态路由匹配

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个User组件,对于所有ID各不相同的用户,都要使用这个组件来渲染。那么,我们可以在vue-router的路由路径中使用动态路径参数”来达到这个效果:当我们在地址后面直接添加任意字符,我们会发现文档内容随着我们的更改而改变。

4.1、动态路由路径

{
	path:/user/:id,//通过$route.params.id可以获取到这个值,如果使用path:/user-* 通配符,是无法获取的
	component:Login
}

<router-link to="/user/1001">登录</router-link>
<router-link to="/user/1002">登录</router-link>


//传递多个参数
{
	path:/user/:id/:uerName,//通过$route.params.id可以获取到这个值,如果使用path:/user-* 通配符,是无法获取的
	component:Login
}

this.$router.push(`/user/${id}/${name}`)

4.2、响应(监听)动态路由参数的变化

 //侦听器:侦听当前路由的变化
  watch: {
    //to:导航之后(跳转之后)的路由对象
    //from:旧值,跳转前的路由对象
    "$route":(to, from)=> {
      console.log("导航之后",to);
      console.log("前",from);
    }
  },
  
官网上是这样写的
  created() {
    //侦听器:侦听当前路由的变化
    this.$watch(() => this.$route.params,
        (toParams, previousParams) => {
          // 对路由变化做出响应...
          console.log(toParams);
          console.log(previousParams);
        })
  },

4.3、捕获所有路径(路由)

路由路径通配符*。
路由列表的匹配模式是自上而下的逐个路由匹配,带有通配符的路由一定放在路由列表最后。

{
        path: "/*",
        component: Error
    }

5、嵌套路由

{
        path: '/about',
        component:About,
        children: [{
            //嵌套路由列表
            // path:"list",//相对路径是上级路由作为前缀路径 to="/about/list"
            path:"/list",//绝对路径不能以上级路由作为前缀路径 to="/list"
            component:Child
        }]
    },

6、编程式导航

6.1、push

//字符串形式
this.$router.push('/vuex');
//对象形式
this.$router.push({path:'/vuex'})

路由在导航之后会形成历史记录history;
push:在历史列表中追加一个

6.2、replace

replace:在历史列表中替换上一个记录,不可以后退到上一个页面;

在声明式导航中的应用:

<router-link to="xxxx" replace>xxx</router-link>

编程式导航:

this.$router.replace('/vuex')

一般可以用在登录后,跳转到主页,就用replace,防止用户回退时回退到登录页面。

6.3、go

历史前进或后退多少步;

this.$router.go(-3)

7、路由配置

7.1、命名路由

为每个路由的配置添加一个name属性,且必须唯一;

{
        path: "/login",
        name:"login",//路由名称
        component: Login
    }

根据路由名称进行导航

//声明式
<router-link :to="{name:'vuex'}" replace>xxx</router-link>

//编程式导航(对象形式,不能是字符串形式)
this.$router.push({name:'vuex'})

7.2、重定向redirect

通过重定向redirect是实现组件的复用;

	{
        path: "/",
        redirect:"/home",
        //redirect: {name: "vuex"}也可以通过组件名称进行重定向
    },
    {
        path: '/home',
        name: 'home',
        component: HomeView
    }

7.3、别名alias

{
        path: '/home',
        name: 'home',
        component: HomeView,
        alias:"/hm"//路由别名
    },

7.7、其他

export default new Router({
    mode: 'history', //路由模式,取值为history与hash
    base: '/', //打包路径,默认为/,可以修改
    routes: [
    {
        path: string, //路径
        ccomponent: Component; //页面组件
        name: string; // 命名路由-路由名称
        components: { [name: string]: Component }; // 命名视图组件
        redirect: string | Location | Function; // 重定向
        props: boolean | string | Function; // 路由组件传递参数
        alias: string | Array<string>; // 路由别名
        children: Array<RouteConfig>; // 嵌套子路由
        // 路由单独钩子
        beforeEnter?: (to: Route, from: Route, next: Function) => void; 
        meta: any; // 自定义标签属性,比如:是否需要登录
        icon: any; // 图标
        // 2.6.0+
        caseSensitive: boolean; // 匹配规则是否大小写敏感?(默认值:false)
        pathToRegexpOptions: Object; // 编译正则的选项
    }
    ]
})

8、路由传参

两个组件之间的数据传递;

8.1、query

  1. 字符串拼接形式
<router-link to="/VModel?name=user&pwd=123"></router-link>

//接收参数
this.$route.query

在这里插入图片描述

  1. 以对象的形式
//传递的是一个对象,也可以拼接为字符串形式
this.$router.push({path:'/vuex',query:{name:'111',age:18}})

//接收参数
this.$route.query

8.2、params

  1. 动态路由匹配传递参数(路径传参)
    这种方式必须传参
 {
        path: '/vuex/:ids/:name',
        name: 'vuex',
        component: VueXStudy,
    }

<router-link to="/vuex/1/xiao">xxxx</router-link>


//接收参数
this.$route.params

在这里插入图片描述

  1. 编程式导航传参
  • 参数隐藏,不在路径中出现
  • 路径固定
  • 必须通过name导航
this.$router.push({name:'vuex',params:{name:'张三',age:18}})

//接收参数
this.$route.params

在这里插入图片描述

  1. 声明式导航传参
<router-link :to="{name:'vuex',params:{name:'李四'}}">xxxx</router-link>

//接收参数
this.$route.params

8.3、props

在组件中使用$route会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的url使用,限制了其灵活性。

解耦

{
        //路由路径中的占位符名称必须与组件props变量名称一致
        
        path: '/vuex/:id/:userName',
        name: 'vuex',
        component:VueXStudy,
        //在路径配置中开启props传参
        props: true
    }
    
<router-link to="/vuex/1001/王麻子">xxxx</router-link>

//定义props对象接收路由参数
props:{
    id:String,
    userName:String
  }

8.4、query 和 params的区别

  1. query 可以使用path和name,params只能使用name
  2. query传参刷新后可以保存,params不会保存;
  3. query传递的参数会显示在url地址中,params不会显示;
  4. 通过字符串拼接的形式传递参数,使用的是$route.query接收参数;
  5. query不可以和动态路由匹配一起使用,而使用params接收参数

9、导航守卫

“导航”表示路由正在发生变化;
类似于javaweb里面的过滤器,拦截器

9.1、全局前置守卫

router.beforeEach()一般用来做一些进入页面的限制。比如没有登录,就不能进入某些页面,只有登录了之后才有权限查看某些页面。说白了就是路由跳转前根据业务逻辑判断是否拦截。

router.beforeEach(回调函数),回调函数中的三个参数

  1. to:将要导航到的路由对象
  2. from:导航之前的路由对象
  3. next:导航函数,在函数执行时,此函数必须执行一次,且仅能执行一次
next():无参数调用就是对导航的放行;
next(阻止导航,阻止导航后跳转的路径):阻止导航,阻止路由跳转

//有参数时编写的形式:
next( '/login')
next({path: '/login'})
next({name: 'login'})
//前置守卫
//模拟身份认证:判断用户是否登录,如果没有登录,跳转至登录页面
router.beforeEach((to, from, next) => {//路由跳转中
    if (to.path == "/") {//"/"默认进入登录页面
        next();
    } else {
        if (sessionStorage.getItem("userInfo")) {
            next()
        } else {
            next({path: '/'})
        }
    }
})

9.2、路由独享守卫

守卫范围:当前路由以及当前路由下的所有嵌套路由;

{
        path: '/vuex',
        name: 'vuex',
        component: () => import( '../components/vuex/VueXStudy.vue'),
        beforeEnter: (to, from, next) => {
            console.log("to", to);
            console.log("from", from);
            next();
        }
    }

10、路由懒加载

未使用懒加载

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'

Vue.use(VueRouter)
export default new VueRouter({
    routes:[
		{
        path: '/home',
        name: 'home',
        component: HomeView,
   		}
	]
})

10.1、vue异步组件实现懒加载

方法如下:component:resolve=>(require(['需要加载的路由的地址']),resolve)

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

Vue.use(VueRouter)
export default new VueRouter({
    routes:[
		{
        path: '/home',
        name: 'home',
        component: resolve=>(require(["../views/HomeView.vue"],resolve)),
   		}
	]
})

10.2、ES6 提出的import方法(最常用,推荐使用)

方法如下: component: () =>import('需要加载的模块地址')

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

Vue.use(VueRouter)
export default new VueRouter({
    routes:[
		{
        path: '/home',
        name: 'home',
        component: () => import( '../views/HomeView.vue')
   		}
	]
})

10.3、webpack提供的require.ensure()实现懒加载

  1. vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。
  2. 这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件
  3. require.ensure可实现按需加载资源,包括js,css等。他会给里面require的文件单独打包,不会和主文件打包在一起。
  4. 第一个参数是数组,表明第二个参数里需要依赖的模块,这些会提前加载。
  5. 第二个是回调函数,在这个回调函数里面require的文件会被单独打包成一个chunk,不会和主文件打包在一起,这样就生成了两个chunk,第一次加载时只加载主文件。
  6. 第三个参数是错误回调。
  7. 第四个参数是单独打包的chunk的文件名

11、vue2中动态添加路由router.addRoute

动态添加根路由:router.addRoute({path:xxx,name:xx....})
动态添加子路由:router.addRoute(parentName,{path:xxx,name:xx....}),其中parentName为父级路由定义的name字段。

你可能感兴趣的:(vue,vue.js,学习,javascript)