vue-router有几种钩子函数
- 全局路由。(全局导航钩子主要有两种钩子:前置守卫、后置钩子。)
to
: Route,代表要进入的目标,它是一个路由对象;from
: Route,代表当前正要离开的路由,同样也是一个路由对象;next
: Function,这是一个必须需要调用的方法,而具体的执行效果则依赖 next 方法调用的参数;
- 路由独享的钩子:
beforeEnter
- 组件内的导航钩子:
beforeRouteEnter
、beforeRouteUpdate
、beforeRouteLeave
beforeRouteEnter
不能获取组件实例 this,因为当守卫执行前,组件实例被没有被创建出来,剩下两个钩子则可以正常获取组件实例 this- 仅仅是
beforRouteEnter
支持给 next 传递回调,其他两个并不支持。因为归根结底,支持回调是为了解决 this 问题,而其他两个钩子的 this 可以正确访问到组件实例,所有没有必要使用回调完整的 vue-router 导航解析流程
1、导航被触发。
2、在失活的组件里调用离开守卫。
3、调用全局的beforeEach
守卫。
4、在重用的组件里调用beforeRouteUpdate
守卫 (2.2+)。
5、在路由配置里调用beforeEnter
。
6、解析异步路由组件。
7、在被激活的组件里调用beforeRouteEnter
。
8、调用全局的beforeResole
守卫 (2.5+)。
9、导航被确认。
10、调用全局的afterEach
钩子。
11、触发 DOM 更新。
12、用创建好的实例调用beforeRouteEnter
守卫中传给 next 的回调函数。
模式
● hash
: 使用 URL hash 值来作路由。默认模式。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器。
● history
: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。
● abstract
: 支持所有 JavaScript 运行环境,如 Node.js 服务端。如果发现没有浏览器API,路由会自动强制进入这个模式。
hash 模式
异步数据请求交互运行在不刷新浏览器的情况下进行。而异步交互体验的更高级版本就是 SPA —— 单页应用。单页应用不仅仅是在页面交互是无刷新的,连页面跳转都是无刷新的,为了实现单页应用,所以就有了前端路由。
在改变url的情况下,保证页面的不刷新。
早期基于location.hash来实现,hash 值的变化,并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。另外每次 hash 值的变化,还会触发hashchange 这个事件,通过这个事件我们就可以知道 hash 值发生了哪些变化。然后我们便可以监听hashchange来实现更新页面部分内容的操作
- URL中hash值只是客户端的一种状态,也就是说当向服务器发出请求时,hash部分不会被发送
- hash值的改变,都会在浏览器的访问历史中增加一个记录,因此我们能通过浏览器的回退、前进按钮控制hash的切换
- 可以通过a标签,并设置href属性,当用户点击标签后,URL的hash值会发生改变;或者使用JS来对location.hash进行复制,改变hash值
- 可以使用hashchange事件监听hash值的变化,从而对页面进行操作和渲染 ```javascript function matchAndUpdate () { // todo 匹配 hash 做 dom 更新操作 }
window.addEventListener(‘hashchange’, matchAndUpdate)
<a name="NrNY6"></a>
#### history 模式
14年后,因为HTML5标准发布。多了两个 API,pushState 和 replaceState,通过这两个 API 可以改变 url 地址且不会发送请求。同时还有popstate事件。<br />通过这些就能用另一种方式来实现前端路由了,但原理都是跟 hash 实现相同的。<br />用了HTML5的实现,单页路由的url就不会多出一个#,变得更加美观。<br />但因为没有 # 号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。为了避免出现这种情况,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。
```javascript
function matchAndUpdate () {
// todo 匹配路径 做 dom 更新操作
}
window.addEventListener('popstate', matchAndUpdate)
服务器配置
express
可以考虑使用 中间件 [connect-history-api-fallback 中间件](https://github.com/bripkens/connect-history-api-fallback)
nginx
location / {
try_files $uri $uri/ /index.html;
}
node
const http = require('http')
const fs = require('fs')
const httpPort = 80
http.createServer((req, res) => {
fs.readFile('index.html', 'utf-8', (err, content) => {
if (err) {
console.log('We cannot open "index.html" file.')
}
res.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8'
})
res.end(content)
})
}).listen(httpPort, () => {
console.log('Server listening on: http://localhost:%s', httpPort)
})