Vue路由管理

1.什么是路由?

生活中的通过路由器功能来完成不同网络之间数据的传递

  • 后端路由

    浏览器每访问一次新页面的时候,都要向服务器发送请求,然后服务器会响应请求,返回新页面给浏览器,在这个过程中会有一定的网络延迟

    • 后端路由是通过用户请求的URL分发到具体的处理程序,从而使浏览器每次跳转到不同的页面
    • 服务器收到请求后,将数据和模板组合,返回HTML页面。或者直接返回HTML模板,由前端JavaScript程序再去请求数据,使用前端模板和数据进行组合,生成最终的HTML页面

    请添加图片描述

  • 前端路由

    前端路由在访问一个新页面的时候仅仅是变换了一下hash值而已,没有和服务端交互,所以不存在网络延迟,提升了用户体验

    • 前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做
    • 对于单页面应用(SPA)来说,主要通过URL中的hash(#号)来实现不同页面之间的切换。hash有一个特点,就是HTTP请求中不会包含hash相关的内容,所以单页面程序中的页面跳转主要用hash来实现

    请添加图片描述

2.Vue-Router

Vue Router 是 Vue.js 官方的路由管理器,主要用于对URL进行管理实现URL与组件的对应关系,它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌

  • 核心功能

    • 嵌套的路由/视图表
    • 模块化的、基于组件的路由配置
    • 路由参数、查询、通配符
    • 基于 Vue.js 过渡系统的视图过渡效果
    • 细粒度的导航控制
    • 带有自动激活的 CSS class 的链接
    • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
    • 自定义的滚动条行为
  • 工作原理

    • 单页面应用(SPA)的核心思想之一,就是更新视图而不重新请求页面
    • 当在加载页面时不会加载整个页面,而是更新某个指定的容器中的内容,比如组件的切换
    • 对于大多数单页面应用,都推荐使用官方支持的Vue-Router
  • 工作方式

    // main.js文件
    const router = new VueRouter({
        mode: 'history | hash',
        routes: [...]
    })
    
    • hash模式

      vue-router默认为采用hash模式,使用URL的hash来模拟一个完整的URL,当URL改变时,页面不会重新加载

      其中的#就是hash符号,中文名为哈希符或者锚点,在hash符号后的值,称为hash值

      • 路由的hash模式是利用了window可以监听onhashchange事件来实现的,也就是说hash值是用来指导浏览器动作的,对服务器没有影响
      • HTTP请求中也不会包括hash值,同时每一次改变hash值,都会在浏览器的访问历史中增加一个记录,使用“后退”按钮,就可以回到上一个位置
      • hash模式是根据hash值来发生改变,根据不同的值,渲染指定DOM位置的不同数据
    • history模式

      history模式不会出现#号比较美观,这种模式充分利用history.pushState()来完成URL的跳转而且无须重新加载页面

      • HTML5中history有两个新增的API,分别是history.pushState() 和 history.replaceState()
      • 两个方法都接收3个参数,即状态对象(state object)、标题(title)、地址(URL)

3.基本使用

  • route :表示它是一条路由,单数形式
  • routes:表示它是一组路由,把route的每一条路由组合起来,形成一个数组
  • router表示它是一个机制,充当管理路由的管理者角色
  • 匹配原则:同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
	</head>
	<body>
		<div id="app">
			<div>
				<!-- 使用 router-link 组件来导航 -->
				<router-link to="/login" tag="a">登录</router-link>
				<router-link to="/register" tag="a">注册</router-link>
			</div>
			
			<!-- 路由出口,路由匹配到的组件将渲染在这里 -->
			<router-view></router-view>
		</div>

		<script type="text/javascript">
			var login = {
				template: '<div>登录页面</div>'
			}
			var register = {
				template: '<div>注册页面</div>'
			}
            var notFound = {
				template: '<div>404</div>'
			}
			
			var router = new VueRouter({
                # 在创建的routerObj对象中,如果不配置mode,就会使用默认的hash模式
                # 添加mode:'history'之后,将使用HTML5 history模式
                # 该模式下component的属性值,必须是一个组件的模板对象,不能是组件的引用名称
				mode: 'hash',
                routes:[
                	{ path: '/', redirect: '/login' }, 
					{ path: '/login', component: login },
					{ path: '/register', component: register },
                    { path: '*', component: notFound }                   
				]
			})
			
		    var vm = new Vue({
		        el: '#app',
				router: router
		    })
		</script>
	</body>
</html>

4.对象属性

路由对象(route object)表示当前激活的路由的状态信息,包含了当前URL解析得到的信息,还有URL匹配到的路由记录。路由对象是不可变的,每次成功地导航后都会产生一个新的对象。

  • this.router

    表示全局路由器对象,项目中通过router路由参数注入路由之后,在任何一个页面都可以通过此属性获取到路由器对象,并调用其push()、go()等方法

  • this.​route

    表示当前正在用于跳转的路由器对象

    属性名类型说明
    $route.pathString对应当前路由的名字
    $route.queryObject一个{key:value}对象,表示 URL查询参数
    $route.paramsObject一个{key:value}对象,路由转跳携带参数
    $route.hashString在history模式下获取当前路由的hash值(带#),如果没有hash值,则为空字符串
    $route.fullPathString完成解析后的URL,包含查询参数和hash的完整路径
    $route.nameString当前路由的名称
    $route.matchedArray路由记录,当前路由下路由声明的所有信息,从父路由(如果有)到当前路由为止
    $route.redirectedFromString如果存在重定向,即为重定向来源的路由

5.动态路由

  • 默认的路由方式都是严格定义匹配好的,只有router-link中的to属性和JavaScript中定义的路由中的path的值一样时,才会显示对应的component

  • 动态路由是指根据不同的条件动态的去配置路由规则。在vue-router的路由路径中,可以使用动态路径参数给路径动态的传值

  • 动态路由在来回切换时,由于它们都是指向同一组件,Vue不会销毁再重新创建这个组件,而是复用这个组件

  • 监听路由

    # 在组件内部利用watch来监听$route的变化
    watch: {
      $route (to, from) {
        console.log(to)		// to表示要去的那个组件
        console.log(from)	// from表示从哪个组件过来的
      }
    }
    
  • 路由传参

    • query方式

      通过query方式传递参数,使用path属性给定对应的跳转路径(类似于GET请求)

      <div id="app">
        <router-link to="/login?name=admin&pass=123">登录</router-link>
        <router-view></router-view>
      </div>
      
      var login = {  // 定义user组件
          template: 
          	'<h3>用户: {{$route.query.name}} 密码: {{$route.query.pass}}</h3>',
          created () {
              console.log(this.$route)	// 用this.$route来接收参数
          }
      }
      var router = new VueRouter({
          routes: [ 
              { path: '/login', component: login }
          ]
      })
      var vm = new Vue({
          el: '#app',
          router 
      })
      
    • params方式

      使用params方式不需要通过查询字符串传参,通常会搭配路由的history模式,将参数放在路径中或隐藏

      <div id="app">
        <router-link to="/login/admin/123">登录</router-link>
        <router-view></router-view>
      </div>
      
      var login = {  // 定义user组件
          template: 
          	'<h3>用户: {{$route.params.name}} 密码: {{$route.params.pass}}</h3>',
          created () {
              console.log(this.$route)	// 用this.$route来接收参数
          }
      }
      var router = new VueRouter({
          routes: [ 
              { path: '/login/:name/:pass', component: login }
          ]
      })
      var vm = new Vue({
          el: '#app',
          router 
      })
      

6.嵌套路由

  • 是否是嵌套路由主要是由页面结构来决定的,一个应用界面,通常由多层嵌套的组件组合而成。简而言之,嵌套路由就是在路由里面嵌套它的子路由
  • 嵌套子路由的关键属性是childrenchildren也是一组路由,相当于routes
<div id="app">
    <div>
        <router-link to="/home" tag="a">首页</router-link>
    </div>
    <router-view></router-view>
</div>
<template id="home">
    <div class="home">
        <div>
            <router-link to="/home/login" tag="a">登录</router-link>
            <router-link to="/home/register" tag="a">注册</router-link>
        </div>
        <router-view></router-view>
    </div>
</template>
 var home = {
     template: '#home'
 }
 var login = {
     template: '<div>登录页面</div>'
 }
 var register = {
     template: '<div>注册页面</div>'
 }
 var notFound = {
     template: '<div>404</div>'
 }

 var router = new VueRouter({
     routes:[
         { 
             path: '/home', 
             component: home,
             children:[
                 { path: 'login', component: login },
                 { path: 'register', component: register },
                 { path: '', component: home }
             ]
         },
         { path:'*', component: notFound }           
     ]
 })

 var vm = new Vue({
     el: '#app',
     router: router
 })

7.命名视图

  • 在开发中,有时候想同时或同级在一个页面中展示多个视图,而不是嵌套展示,则可以在页面中定义多个单独命名的视图
  • 也就是在<router-view>上定义name属性表示某个视图的名字,然后就可以根据不同的name值展示不同的页面,如果<router-view>没有设置name属性,那么默认为default
<div id="app">
    <div>
        <router-view></router-view>
        <div>
            <router-view name="left"></router-view>
            <router-view name="main"></router-view>
        </div>
        <router-view name="footer"></router-view>
    </div>
</div>
var header = { template: '<div>我是头部</div>' }
var left = { template: '<div>我是侧边栏</div>' }
var main = { template: '<div>我是主体</div>' }
var footer = { template: '<div>我是底部</div>' }

var router = new VueRouter({
    mode: 'hash',
    routes:[
        { path: '/', redirect: '/index' }, 
        { 
            path: '/index',
            components: {'default':header,'left':left,'main':main,'footer':footer}
        }
    ]
})

var vm = new Vue({
    el: '#app',
    router: router
})

8.命名路由

vue-router提供了一种隐式的引用路径,即命名路由。可以在创建Router实例的时候,在 routes中给某个路由设置名称name值作为标识,然后就可以通过这个名称来代替path路径去指向某个路由组件

<div id="app">
    <div>
        <router-link 
                     :to="{name:'login',params:{username:admin,password:123}}">
            <span>登录</span>
        </router-link>
    </div>
    <router-view></router-view>
</div>
var login = {
    template: '<div>登录页面</div>',
    created () { 
        console.log(this.$route) 
    }
}

var router = new VueRouter({
    mode: 'hash',
    routes:[
        { path: '/', redirect: '/login' }, 
        { 
            path: '/login/:username/:password',
            name: 'login',
            component: login 
        }           
    ]
})

var vm = new Vue({
    el: '#app',
    router: router
})

9.编程式导航

为了更方便地在项目中开发导航功能,Vue提供了编程式导航,也就是利用JavaScript代码来实现地址的跳转

  • router.push()

    类似与BOM操作中的window.history.pushState

    声明式编程式
    <router-link :to="...">router.push(...)
    • 定义方式
    var router = new VueRouter()
    
    // 字符串形式
    router.push('user')
    // 对象形式
    router.push({ path: '/login?url=' + this.$route.path })
    // 命名路由
    router.push({ name: 'user', params: { userId: 123 }})
    // 带查询参数 /user?id=1
    router.push({ path: 'user', query: { id: '1' }})
    
    router.push({ name: 'user', params: { userId:123 }})
    router.push({ path: '/user/123' })  
    
    // path和params搭配使用时params不生效
    router.push({ path: '/user', params: { userId:123 }})
    
    • query方式
    <div id="app">
      <button @click="login">登录</button>
      <router-view></router-view>
    </div>
    
    var login = {
        template: '<p>登录用户名:{{ this.$route.query.name }}</p>'
    } 
    
    var router = new VueRouter({ 
        routes: [ 
            { path: '/login', component: login }
        ]
    })
    
    var vm = new Vue({
        el: '#app',
        methods: {
            login () {
                this.$router.push({ path: '/login', query: { name: 'admin' } })
            }
        },
        router
    })
    
    • params方式
    <div id="app">
      <button @click="login">登录</button>
      <router-view></router-view>
    </div>
    
    var login = {
        template: '<p>登录用户名:{{ this.$route.params.name }}</p>'
    } 
    
    var router = new VueRouter({ 
        routes: [ 
            { path: '/login', name: 'login', component: login }
        ]
    })
    
    var vm = new Vue({
        el: '#app',
        methods: {
            login () {
                this.$router.push({ name: 'login', params: { name: 'admin' } })
            }
        },
        router
    })
    
  • router.replace

    和router.push类似,只不过导航后不会向history栈添加新的记录,而是替换当前的history记录,类似与BOM操作中的window.history.replaceState

    声明式编程式
    <router-link :to="..." replace>router.push(...)
  • router.go

    这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似与BOM操作中的window.history.go(n)

    // 在浏览器记录中前进一步,等同于 history.forward()
    this.$router.go(1)
    
    // 在浏览器记录中后退一步,等同于 history.back()
    this.$router.go(-1)
    

10.重定向和别名

  • 重定向

    const router = new VueRouter({
        routes: [
            # 重定向到一个path
            { path: '/a', redirect: '/b' },
            # 重定向到一个name        
            { path: '/a', redirect: { name: 'b' }},
        	# 通过返回值重定向
            { path: '/a', redirect: to => {
                return/b‘
            }}
        ]
    })
    
  • 起别名

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

11.路由组件传参

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

  • 未解耦

    const User = {
        template: '<div>User {{ $route.params.id }}</div>'
    }
    const router = new VueRouter({
        routes: [
            { path: '/user/:id', component: User }
        ]
    })
    
  • 解耦后

    const User = {
        props: ['id'],
        template: '<div>User {{ id }}</div>'
    }
    const router = new VueRouter({
        routes: [
            { path: '/user/:id', component: User, props: true },
    
            // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
            {
                path: '/user/:id',
                components: { default: User, sidebar: Sidebar },
                props: { default: true, sidebar: false }
            }
        ]
    })
    
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程小吉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值