vue 学习——路由

Vue路由实现原理
浅谈vue-router原理

路由原理

更新视图但不重新请求页面,是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有2种方式:hash和history interface,mode取值其实还有abstract,用于非浏览器的情况。

hash方式主要是通过url中的#,在HTML中#是锚点,指向页面中的位置,#后面的数据改变,不会重新请求页面。通过hashchange监听实现更新页面操作。在vue中,hash模式主要是创建HashHistory对象,然后通过调用push和replace来更改路由。

html5中的history interface,它提供了访问浏览器历史记录栈的接口,通过go()/back()/forward()来读取历史记录,通过pushState() 和 replaceState() 修改路由。同时通过监听onpopstate()监听地址变化。

1. 利用URL中的hash("#");

在初始化对应的history之前,会对mode做一些校验:若浏览器不支持HTML5History方式(通过supportsPushState变量判断),则mode设为hash;若不是在浏览器环境下运行,则mode设为abstract;

abstract模式:其原理为用一个数组stack模拟出浏览器历史记录栈的功能。

VueRouter类中的onReady(),push()等方法只是一个代理,实际是调用的具体history对象的对应方法,在init()方法中初始化时,也是根据history对象具体的类别执行不同操作

2. 利用History interface在HTML5中新增的方法;

History interface是浏览器历史记录栈提供的接口,通过back(),forward(),go()等方法,我们可以读取浏览器历史记录栈的信息,进行各种跳转操作。
从HTML5开始,History interface提供了2个新的方法:pushState(),replaceState()使得我们可以对浏览器历史记录栈进行修改:

window.history.pushState(stateObject,title,url)
window.history,replaceState(stateObject,title,url)

stateObject:当浏览器跳转到新的状态时,将触发popState事件,该事件将携带这个stateObject参数的副本
title:所添加记录的标题
url:所添加记录的url

这2个方法有个共同的特点:当调用他们修改浏览器历史栈后,虽然当前url改变了,但浏览器不会立即发送请求该url,这就为单页应用前端路由,更新视图但不重新请求页面提供了基础。

一、hashchange

hash虽然出现在url中,但不会被包括在http请求中,它是用来指导浏览器动作的,对服务器端完全无用,因此,改变hash不会重新加载页面。

每一次改变hash(window.location.hash),都会在浏览器访问历史中增加一个记录。

可以为hash的改变添加监听事件:window.addEventListener("hashchange",funcRef,false)
通过监听hashchange事件,可以监听到url上锚点数据(#xxx)的改变,可以获取这个事件。

window.addEventListener('hashchange',function(){
	console.log(location.hash);
	//锚点值,即#以及后面的字符
})

利用hash的以上特点,就可以来实现前端路由"更新视图但不重新请求页面"的功能了。

SPA(单页应用)页面不跳转,只通过局部数据改变。

<body>
	<a href="#login">登录</a>
	<a href="#register">注册</a>
	<div id = "main"></div>
</body>
<script type="text/javascript">
	var mainPage = document.getElementById("main")
	window.addEventListener('hashchange',function(){
		console.log(location.hash);
		//锚点值
		switch(location.hash){
			case "#login" :
				mainPage.innerHTML = "登录页面";
				break;
			case "#register" :
				mainPage.innerHTML = "注册页面";
				break;
				
		}
	})
</script>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zJhxKrWX-1634009689031)(路由_files/1.gif)]

<body>
	<div id="app">
		<router-link :to="{name:'login'}">登录</router-link>
		<router-link to="/register">注册</router-link>
		<!-- 路由出口 -->
		<!-- 路由匹配到的组件将渲染在这里 -->
		<router-view></router-view>
	</div>
</body>
<script type="text/javascript">
	var Login = {
		template: '<h2>login</h2>'
	}
	var Reg = {
		template: `<h2>Register</h2>`
	}
	// 2、Vue使用vueRouter插件
	Vue.use(VueRouter);
	// 3、创建一个路由对象实例
	var router = new VueRouter({
		// 4、配置路由对象
		//路由对象赋予name,那么在修改path的时候,不需要改其他引用路由的地方
		//这里是routes不要写错了,否则路由有变化但不会加载页面
		routes: [
			{
				<!-- 命名路由 -->
				name:'login',
				path: '/mylogin',
				component: Login
			},
			{
				path: '/register',
				component: Reg
			}
		]
	})

	// 5、 将配置好的路由对象关联到Vue实例中
	new Vue({
		el: '#app',
		router: router,
	});
</script>

二、$router 和 $route

$router 路由操作对象,只写

this.$router.push({name:"login",params:{id:2}});
//router-link方式
<router-link :to="{path:'/mylogin',query:{str:'hehe'}}">登录</router-link>

$route 路由信息对象,只读

this.$route.params.id   //'2'
this.$route.query.str   //'hehe'

三、嵌套路由

{	
	path: '/register',
	component: Reg,
	children:[{
		name:'register.women',
		path:'women',
		component:Women,
	}]
}
//注册页面中要加上<router-view>作为子路由的出口
var Reg = {
	template: `
		<div>
		<h2>Register</h2> 
		<router-view></router-view>
		</div>`
}

//调用
<router-link  :to='{name:"register.women"}'>跳转子路由</router-link>
  1. 如果子路由的path加了/,那么url显示就不包括父路由
  2. 路由meta元数据:对于路由规则是否需要验证权限的配置
  3. 路由钩子:权限控制的函数执行时期
router.beforeEach(function(to,from,next){})

四、路由中的component和components

  1. component 是常规路由中的组件配置名(例子如上)
  2. components 是命名视图中的组件配置名

<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
//一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):

const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})

五、路由组件传参

$route 或者 props

六、导航守卫

  1. 当离开一个页面时,导航被触发
  2. 执行组件内守卫beforeRouteLeave
  3. 调用全局前置守卫 beforeEach
  4. 在重用组件里面调用 beforeRouteUpdate
  5. 在路由配置里面调用 beforeEnter
  6. 解析异步路由组件
  7. 在激活的组件里面调用 beforeRouteEnter
  8. 调用全局解析守卫beforeResolve
  9. 导航被确认
  10. 调用全局后置守卫 afterEach钩子
  11. 触发DOM更新
    beforeEach
  12. 在重用组件里面调用 beforeRouteUpdate
  13. 在路由配置里面调用 beforeEnter
  14. 解析异步路由组件
  15. 在激活的组件里面调用 beforeRouteEnter
  16. 调用全局解析守卫beforeResolve
  17. 导航被确认
  18. 调用全局后置守卫 afterEach钩子
  19. 触发DOM更新
  20. 创建好的实例调用 beforeRouterEnter守卫中传给next的回调函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
全局路由守卫是Vue Router提供的一种功能,用于在路由切换前和切换后执行一些操作。全局路由守卫包括前置守卫和后置守卫。 前置守卫在每次路由切换之前被调用,可以用来进行一些权限验证、登录状态检查等操作。可以通过调用`router.beforeEach`方法来注册前置守卫。 后置守卫在每次路由切换之后被调用,可以用来进行一些页面切换后的操作,比如页面滚动到指定位置等。可以通过调用`router.afterEach`方法来注册后置守卫。 在Vue Router的路由器实例中,可以通过创建并暴露一个路由器对象来使用全局路由守卫。例如: ```javascript // 创建并暴露一个路由器 const router = new VueRouter({ ... }) // 全局前置路由守卫——初始化的时候被调用、每次路由切换之前被调用 router.beforeEach((to, from, next) => { // 在这里进行权限验证、登录状态检查等操作 // 如果验证通过,调用next()方法继续路由切换,否则调用next(false)取消路由切换 }) // 全局后置路由守卫——初始化的时候被调用、每次路由切换之后被调用 router.afterEach((to, from) => { // 在这里进行页面切换后的操作,比如页面滚动到指定位置 }) export default router ``` 通过以上代码,我们可以在全局范围内使用前置守卫和后置守卫来实现一些通用的路由操作。\[2\] 参考资料: \[1\] 《vue2进阶篇:路由》第13章:vue-router之使用“全局路由守卫” \[2\] 《vue2进阶篇:路由》第10章:vue-router #### 引用[.reference_title] - *1* *2* *3* [vue2进阶篇:vue-router之“使用组件内路由守卫”](https://blog.csdn.net/a924382407/article/details/125742226)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值