本文主要是介绍后端人眼中的Vue(四),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
十、路由router
10.1、路由简介
说起路由,你会想到啥?
路由器,那路由器是用来做什么的,你有没有想过?
- 路由时决定数据包从来源到目的地的路径;
- 将输入端的数据转移到合映射表适的输出端;
- 路由中最重要的概念就是路由表:路由表的本质就是一个映射表,决定了数据包的指向。
10.2 路由分类
10.2.1、后端路由
早期的网站开发整个HTML页面是由服务器来渲染的。服务器将渲染好的对应的HTML页面返回给客户端进行展示,但是一个网站包含很多页面,那服务器是怎么处理的呢?
每个页面都有对应的网址,也就是URL,URL会发送给到服务器,服务器会通过正则对该URL进行匹配,最后交给Controller进行处理。Controller进行处理,最终生成HTML或者数据,然后返回给前端,这其实就是服务器的一个IO操作,这其实就是对后端对路由的解析。这种后端渲染的好处,相对于发送ajax请求拿数据,可以提高首屏渲染的性能,也有利于SEO的优化。但是后端路由转发也是有缺点的:
- 另一种情况是前端开发人员如果要开发页面, 需要通过PHP和Java等语言来编写页面代码。
- 而且通常情况下HTML代码和数据以及对应的逻辑会混在一起, 编写和维护都是非常糟糕的事情
10.2.2、前端路由
10.2.2.1、前端路由简介
随着Ajax的出现,有了前后端分离的开发模式,后端只提供API来返回数据(json,xml),前端通过Ajax获取数据,并且可以通过JavaScript将数据渲染到页面中,这样做最大的优点就是前后端责任的清晰, 后端专注于数据上, 前端专注于交互和可视化上,也就是我们常说的解耦,并且当移动端(iOS/Android)出现后, 后端不需要进行任何处理, 依然使用之前的一套API即可,目前很多的网站依然采用这种模式开发。
在单页面应用阶段,SPA最主要的特点就是在前后端分离的基础上加了一层前端路由,也就是前端来维护一套路由规则。那么前端路由的核心是什么呢?改变URL,但是页面不进行整体的刷新。
10.2.2.2、前端路由规则
10.2.2.2.1、hash(哈希)路由
URL的hash也就是锚点(#), 本质上是改变window.location
的href
属性,我们可以通过直接赋值location.hash来改变href, 但是页面不发生刷新。
10.2.2.2.2、HTML5的history模式
history接口时HTML5新增的,它有5种模式改变URL而不刷新页面。
history.pushState(data, title, url)
history.replaceState(data, title, url)
history.go(-1):返回上一页
history.back():等价于 history.go(-1)
history.forward():等价于 history.go(1)
10.3、Vue-router基本使用
通过使用Vue-router,可以使得Vue开发变得更加灵活,他可以根据前端请求对应的url在页面中展示不同的组件。
目前前端流行的三大框架,都有自己的路由实现:
- Angular的ngRouter
- React的ReactRouter
- Vue的vue-router
10.3.1、认识vue-router
vue-router是Vue的官方路由插件,它和Vue是深度集成的,适合用于构建单页面应用 https://router.vuejs.org/zh/ 。
vue-router是基于路由和组件的,路由用于设定访问路径, 将路径和组件映射起来。在vue-router的单页面应用中, 页面的路径的改变就是组件的切换,让构建单页面应用更简单。
10.3.2、安装vue-router
vue-router是依赖于Vue.js,所以vue-router的加载要在Vue.js的下面。可以去下载也可以通过在线引用的方式进行引用,官方给了一个CDN地址:https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js
。
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title></title><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script src="https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js"></script>
</head><body><div id='app'></div>
</body></html>
<script>// 登录组件login = {template:'<h1>用户登录</h1>'}// 注册组件reg = {template:'<h1>用户注册</h1>'}// 创建路由规则对象const router = new VueRouter({// 配置路由规则routes: [ // 当以login访问时,访问对应login组件{path:'/login',component:login},{path:'/reg',component:reg},]})new Vue({el: '#app',data: {},methods: {},router, // 注册路由,根据ES6语法,变量名等于参数名可以直接省略,只写一遍});
</script>
我们会发现,他报错了。
原因可能是可能是使用 vue-router 版本过高。这是未修改前的。
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script src="https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js"></script>
修改为这样即可,不会报错了。
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script><!-- 低版本,也可以使用 --><script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
我们此时会发现地址栏有点奇怪的变化,有一个#
。
这个#
实际上叫做哈希路由。
编写好注册好组件以后,应该怎么显示呢?我们需要使用显示路由组件的标签。
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title></title><script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script><!-- 低版本,也可以使用 --><!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> --><script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script></head><body><div id='app'><!-- 显示路由组件标签 --><router-view ></router-view></div>
</body></html>
<script>// 登录组件login = {template: '<h1>用户登录</h1>'}// 注册组件reg = {template: '<h1>用户注册</h1>'}// 创建路由规则对象const router = new VueRouter({// 配置路由规则routes: [// 当以login访问时,访问对应login组件{ path: '/login', component: login },{ path: '/reg', component: reg },]})new Vue({el: '#app',data: {},methods: {},router, // 注册路由,根据ES6语法,变量名等于参数名可以直接省略,只写一遍});
</script>
加了显示路由组件的标签后,刷新还是没有任何反应,该怎么访问呢?还记得我们写过的路由规则吗?我们要加上对应的名字才可以访问,比如说我访问登录组件,就加一个/login
。
改为/reg
后,就会切换到注册组件。
如果我们胡乱写一个,没有匹配对应的路由,那么就啥也不显示。
这样还是很不方便,我们作为开发者知道切换/
后面的名字就可以切换组件,但是用户不一定知道哇,所以就可以给用户做一个菜单,用户直接点击即可切换。
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title></title><script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script><!-- 低版本,也可以使用 --><!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> --><script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script></head><body><div id='app'><a href="">登录</a><a href="">注册</a><!-- 显示路由组件标签 --><router-view ></router-view></div>
</body></html>
<script>// 登录组件login = {template: '<h1>用户登录</h1>'}// 注册组件reg = {template: '<h1>用户注册</h1>'}// 创建路由规则对象const router = new VueRouter({// 配置路由规则routes: [// 当以login访问时,访问对应login组件{ path: '/login', component: login },{ path: '/reg', component: reg },]})new Vue({el: '#app',data: {},methods: {},router, // 注册路由,根据ES6语法,变量名等于参数名可以直接省略,只写一遍});
</script>
那a
标签里面的href
属性怎么写呢?不可以写绝对路径,这样项目上线的时候,这里全部都要改,一点也不灵活。我们可以使用#/login
的方式,用#
告诉Vue,我这是一个路由的切换。#
后面跟上路由名字。不加#
Vue会把他当成一个绝对地址,而不是路由切换。
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title></title><script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script><!-- 低版本,也可以使用 --><!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> --><script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script></head><body><div id='app'><a href="#/login">登录</a><a href="#/reg">注册</a><!-- 显示路由组件标签 --><router-view ></router-view></div>
</body></html>
<script>// 登录组件login = {template: '<h1>用户登录</h1>'}// 注册组件reg = {template: '<h1>用户注册</h1>'}// 创建路由规则对象const router = new VueRouter({// 配置路由规则routes: [// 当以login访问时,访问对应login组件{ path: '/login', component: login },{ path: '/reg', component: reg },]})new Vue({el: '#app',data: {},methods: {},router, // 注册路由,根据ES6语法,变量名等于参数名可以直接省略,只写一遍});
</script>
10.3.3、切换路由
10.3.3.1、标签切换
每次都打#
还挺麻烦的,所以Vue给了切换路由的标签router-link>
,当我们写了一个router-link
标签时,发现啥也不显示,这是因为我们还要写to
这个属性,表明切换到哪个组件。
我们可以看到,他的底层也是a
标签。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-drhXmOKX-1673761553967)(https://gitee.com/ljpxx/study-note/raw/master/202301151341528.png)]
to
属性里面写/组件名称
,省去写#
,这是最简单的写法。
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title></title><script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script><!-- 低版本,也可以使用 --><!-- <script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script> --><script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script></head><body><div id='app'><a href="#/login">登录</a><a href="#/reg">注册</a><!-- 显示路由组件标签 --><router-view ></router-view><router-link to="/login">我是路由切换,用户登录</router-link></div>
</body></html>
<script>// 登录组件login = {template: '<h1>用户登录</h1>'}// 注册组件reg = {template: '<h1>用户注册</h1>'}// 404组件noFound = {template: '<h1>404页面</h1>'}// 创建路由规则对象const router = new VueRouter({// 配置路由规则routes: [// 当以login访问时,访问对应login组件{ path: '/login', component: login },{ path: '/reg', component: reg },// 重定向,一开始就跳转到login组件中{path:'/',redirect: '/login'},{path:'*',component:noFound}]})new Vue({el: '#app',data: {},methods: {},router, // 注册路由,根据ES6语法,变量名等于参数名可以直接省略,只写一遍});
</script>
他的完整写法是在to
里面写一个路由规则对象。类似这样::to=path{'/login'}
我们不仅可以通过路径切换路由,还可以通过名称来切换路由,通过路由对象名称切换路由,显示不同的组件,想根据名称切换路由只能使用router-link
。
首先我们在注册组件的时候,要先指定一个名称,即name
属性。
// 创建路由规则对象const router = new VueRouter({// 配置路由规则routes: [// 当以login访问时,访问对应login组件{ path: '/login', component: login,name:'Login' },{ path: '/reg', component: reg },// 重定向,一开始就跳转到login组件中{path:'/',redirect: '/reg'},{path:'*',component:noFound}]})
在使用名称切换路由时,用name
这个属性来切换。推荐使用这种方式来切换路由,使用命名切换路由更加解耦合。
<router-link :to="{name:'Login'}">我是路由切换,用户登录</router-link>
10.3.3.2、Js切换路由
我们还可以通过Js代码中切换路由。this中有两个属性:
- this.$route:表示当前路由对象。
- this.$router:表示路由管理器对象(VueRouter)。
使用Js代码,用路由器管理对象去切换当前路由对象,即可切换路由。
this.$router.push({path:'/login'}) // 根据路径切换路由
this.$router.push('/login') // 根据路径切换路由简化写法
this.$router.push({name:'Login'}) // 根据名字切换路由,这是我们推荐的
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>vue系列课程</title>
</head>
<body><div id="app"><h1>{{msg}}</h1><!--切换路由: 1.通过标签直接切换 2.在js代码中切换--><router-link :to="{name:'Login'}">用户登录</router-link><router-link :to="{name:'Register'}">用户注册</router-link><!--2.在js代码中切换路由--><button @click="login">用户登录</button><button @click="register">用户注册</button><!--展示路由组件标签--><router-view/></div>
</body>
</html>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<!-- 低版本,也可以使用 -->
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js"></script>
<script>//loginconst login = {template:`<div><h4>用户登录</h4></div>`};//registerconst register = {template:`<div><h4>用户注册</h4></div>`};//1.创建路由规则对象const router = new VueRouter({routes:[//name:这个属性代表路由对象名称 用来给路由对象一个唯一名称标识{path:'/login',component:login,name:'Login'},{path:'/register',component:register,name:'Register'},]});//解决同一个路由多次切换报错的问题const originalPush = VueRouter.prototype.push;VueRouter.prototype.push = function push(location) {return originalPush.call(this, location).catch(err => err)};const app = new Vue({el: "#app",data: {msg:"vue router 基本使用之在js代码中切换路由"},methods:{login(){//发送axios请求完成登录 响应回来之后切换路由到主页//this.$route object 当前路由对象 this.$router vueRouter 代表路由管理器对象//console.log(this.$route.name);//this.$router.push('/login');//切换路由//this.$router.push({path:'/login'});//在vuerouter 中多次切换相同路由出现错误 1.每次切换之前手动判断 2.加入官方一段配置解决错误问题// if(this.$route.name!='Login'){// this.$router.push({name:'Login'});//使用名称切换// }this.$router.push({name:'Login'});//使用名称切换},register(){//console.log(this.$route.name);// if(this.$route.name!='Register') {// this.$router.push({name: 'Register'});//使用名称切换// }this.$router.push({name: 'Register'});//使用名称切换}},router,//注册路由对象});
</script>
10.3.2.3、切换路由之传递参数
他支持两种方式的传参:
- queryString方式:即url拼接参数,通过
this.$route.query.key
来直接获取。 - restful风格传参:即路径传参。
在使用queryString方式传递参数的时候,参数都在query里面。
如果通过<router-link>
的方式传递多个参数可以这样写。
<router-link :to="{path:'/login?name=xiaolin&password=123456'">用户登录</router-link>
检验一下是否可以传递参数。
console.log(this.$route.query.name+"=====");//获取当前路由对象console.log(this.$route.query.password+"=====");//获取当前路由对象
在通过queryString方式传递参数的时候,Vue底层本质上是把他封装到query对象里面去,我们也可以直接把他封装到query对象里面。
<router-link :to="{name:'Login',query:{name:'xiaoxiaolin',password:123456}}">用户登录</router-link>
在通过restful传参的时候,我们在定义路由的时候需要修改一下你path
,使用:id
方式告诉Vue这是我传递的参数,参数名为id。
{path:'/register/:id'}
如果有多个参数的时候,可以直接接着往下面拼接。
{path:'/register/:id/:name'}
表示这是传递了两个参数,一个id,一个name。我们可以看到,参数都在params力买买,而不是在path里面。
使用restful方式传参的时候,也可以通过<router-link>
标签的方式进行传参,但是不可以直接在url路径后拼接参数,因为restful方式传参的时候,参数会被封装到params里面去,所以我们可以直接把参数封装到params里面去。
<router-link :to="{path:'/register/22/xiaolin'}">用户注册</router-link>
<router-link :to="{name:'Register',params:{id:233,name:'xiaolin'}}">用户注册</router-link>
这篇关于后端人眼中的Vue(四)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!