在之前的网页开发,其实网页是全由后端渲染的,对数据进行处理和写网页全都是后端开发人员的事情。
后端开发人员在服务器端用html+css+jsp/php写好网页,浏览器通过用户点击获取页面的url,再将url传至服务器,服务器通过收到的url将对应的页面传给浏览器进行显示。
所有事情都交给后端干,肯定是效率低下的。
网页开发因此迈入新阶段。前端开发人员写的html+css+js代码会放在一个静态资源服务器里面,后端开发人员会将前端想要的api放在一个api服务器里面。
浏览器通过用户点击获取页面的url,再将url传给静态资源服务器,静态资源服务器将页面的一套html+css+js传给浏览器。浏览器将html+css进行渲染,运行js代码通过ajax从api服务器获取数据,再将其显示在页面上。
现在部分网站又出现一种新模式,单页面富有应用阶段。
前端人员开发一个网站,首页,介绍等等多个页面,每个页面对应的代码都放在静态资源服务器上。浏览器会下载静态资源服务器上所有的代码,但不会一开始就将其全部渲染,运行。
前端会产生自己的一套路由规则。浏览器通过用户点击获取页面url后,前端不会再将url传至静态服务器获取对应的一套html+css+js代码,而会通过前端路由将页面对应的代码直接渲染,执行。
上面说到,前端路由的核心是改变url,但是页面不进行整体的刷新。
这是什么意思呢?比如淘宝主页的url:www.taobao.com,我们进入其下面的男装分区,可能就是(自己瞎编的):www.taobao.com/nanzhuang。是改变了url的,若是以前的前后端分离阶段,那肯定是改变url,会从服务器获取一套最新页面的html+css+js进行渲染,页面自然整体刷新了。前端路由是在前端进行查找,选择所需的部分代码,那自然就是页面不进行整体刷新了~~~~~~
而在不影响页面整体刷新的前提下改变页面的url有两种方式
location.hash = 'url'
数据结构中有栈的概念
我们可以将history类比为一个栈就很好理解了
这是个“进栈”的方法
history.pushState({},'','url')
page1,page2,page3,page4,page5等等都是在栈里面了,不过当前页面只显示栈顶的url,通过箭头可改变url。
这是个“出栈”的方法
history.back()
history.forwad()
history.go()
//go中是负数,就出栈几个,是正数就进栈几个
history.replaceState({},'','url')
这个方法相对于前面的几种方法有点特殊,它是替代之前的url
在新建项目时我勾选了安装vue-router,所以可直接使用
若是创建项目时没有安装,可以
npm install vue-router --save
安装好后我们会发现src目录下多了个router文件夹,里面的index.js文件就是配置vue的相关信息
vue-router的作用就是为了将url和组件一一对应起来。
当用户首次进入网页时,要点击主页链接才会进入主页。这样就大大降低了用户体验性,所以我们在配置路由映射时一般会首先配置默认路径映射
这样用户每次进入都会自动跳转到首页了。
还有一个问题,我们跳转路径时,会发现url中出现莫名其妙的#,大大影响了可读性。这是因为vue-router默认使用的hash模式,我们将其改为history模式即可
前面我们用到的
给被点击的元素设置class是为了增加样式,你若是觉得class属性值过长,你也可以修改
在有些情况下我们不想使用
对元素监听一个点击方法。每个组件在被注册后都会有一个$router属性,它里面有个push方法,里面写路径就可通过vue-router进行跳转
在开发时我们往往会碰到这样的情况,不同的用户进入“用户”页面,url是不同的,是会随用户id而改变的,那么就需要用到动态路由了
首先新建一个User组件,再在index.js中,将url和其配置
我们可看到,路径最后写的:userId,这个是个被绑定的变量,可在App.vue中看到
不过在真实开发中,当用户点击一个商品时,不只是url动态改变,往往还会获取被点击商品的信息~~~~~
那肯定要写在组件User里:增加一个计算属性,$route.params拿到的是当前活跃的路由的数据
下图可看出使用懒加载后会将js代码打包成多个js文件,用到哪个组件就加载哪个js文件。
组件由组件嵌套,路由同样也有路由嵌套
现在有个需求,首页里面有新闻、信息两个子路由,点击它们可进行相应的组件展示。
那么肯定要有两个组件啊:HomeNews、HomeMessages
在index.js中用懒加载方式引用这两个组件
再在routes中写将路径和组件映射起来(是Home的子路由,那么肯定写在Home的children属性下,注意的是子路由的path最前面不加/)
最后在Home.vue中使用即可
最后通过$route.params.userId可拿到这个值
就是之前传userId的方式,不再叙述
我们通常可以看到我们打开的网页的url的路径后面还会跟一些奇奇怪怪的字符,例如
其实?和它后面的就是query,query里面的articleld就是一个值为104099791的参数
我们将App.vue中的about页面变一下,将它的to属性用对象语法来写,path自然是路径,query中就可以写要传的参数了
举一反三,最后在About.vue中用$route.query.引用参数即可
当我们不用router-link,用一般的标签比如button呢,那就用下面这种写法,其实都是一个道理
params一般只能传一个参数,而query能传一个对象、多个参数。所以可根据传递参数的多少来进行选择,这样看来我觉得query要好一些。
记住两个结论就好:
$router是从vue中引入的整个router对象
因为是从vue中引入的整个router对象,所以它有一系列方法,比如前面用到的push、forward、back等等
$route是当前处于活跃状态(被点击,正在展示)的组件
它是处于活跃状态的组件,那么它的url中的query传的参数自然可以用$route.query.name来引用了
在开发中,我们通过路由在各个组件之间跳转时是希望能够监听跳转的,并做出相应的操作。我们知道路由是将路径和组件一一对应的,我们在开发中往往会有以下需求:Home组件跳转到About组件时谈个窗口提示一下,进入User组件时打印一段话等等,其实导航守卫就是正如它的名字一样对路由之间的跳转进行监听
比如我们有个需求:在前面的操作中我们发现,即使路径从首页跳转到关于、用户啊但是标题没有改。现在我想路径跳转后标题也跟着改变,这就可以用到导航守卫了
既然要改标题,那我们肯定要在每个路由里面添加一个title数据,数据是要放在路由的meta属性里面的
简单来说,下面这个函数就可以说是个导航守卫。router有个beforeEach方法,这个方法会传入一个函数作为参数。这个函数里面有to, from, next三个参数,from, to是两个路由,分别代表跳转前的路由和跳转后的路由。next是一个方法,是必须要写的,不然不能正常显示。
document.title 通过dom选中title元素
to.matched[0].meta.title 获取跳转后的路由的title的值
我们前面用的beforeEach方法是在跳转之前进行的操作,比如afterEach方法是在跳转之后进行的操作,还有些其他方法详见vue-router官网。
由于我感觉keep-alive涉及到了一些深层次的东西,有点没搞懂,所以准备用到的时候再回看这个东西
https://www.bilibili.com/video/av59594689?p=116
https://www.bilibili.com/video/av59594689?p=117