前些天去网易面试,太紧张了结果犯了不少的错,很多还是简单的错。
现在回想起来,还是觉得js的知识点掌握的不行,有些东西了解了却没有去尝试,所以一知半解,在面试官面前完全暴露出来。
感谢网易的2位面试官,让我发现了不少自身的漏洞
好了,开始正题吧
面试官:你用vue开发,那vue-router是怎么实现页面跳转的
我脱口而出,我用history……
事后想想,地址栏这么大一个#在那里,我在睁眼说什么瞎话……面试官怕不是已经扶额了……
来记录一下hash和history的区别和一些小点吧
1.history
介绍history的文章已经很多了,本身history不算太复杂,主要有以下几个东西
(1)window.history.pushState(obj, title [, url])
(2)window.history.replaceState(obj, title [, url])(3)一个popstate事件,在前进和后退调用时触发
来段代码
<body> <p>随机生成的数字是: <span id="num"></span></p> <button onclick="random()">随机生成</button> <script> function random () { var num = parseInt(Math.random() * 100) document.getElementById('num').innerHTML = num window.history.pushState({num: num},'', num); } window.addEventListener('popstate', function (e) { console.log('active') document.getElementById('num').innerHTML = e.state.num }) </script>
但是,直接用是不行的,如果你把这个html文件直接在浏览器里打开,按几下按钮,会出现
Uncaught DOMException: Failed to execute 'pushState' on 'History': A history state object with URL 'file:///E:/buildDisplay/4' cannot be created in a document with origin 'null' and URL
其实这个错只是让你跑个服务器而已,简单的nodejs写一个就好了,这不是重点
var express = require('express') var app = express() var path = require('path'); var router = express.Router() app.get('/testHistory', function (req, res) { res.sendFile(path.join(__dirname, './test.html')) }) app.listen(5001, function (data) { console.log('server listened at 5001') })
效果,没有问题
注意:
<1>这样改变url,并不会向后台发送请求,后退也不会
<2>但是,一旦刷新了,那真的去请求了,而后台往往没有这个路由,然后就404了
所以,在vue-router使用history模式的时候,有这样一句提示
当你使用 history 模式时,URL 就像正常的 url,例如
http://yoursite.com/user/id
,也好看!不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问
http://oursite.com/user/id
就会返回 404,这就不好看了。所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个
index.html
页面,这个页面就是你 app 依赖的页面。
2.hash
hash相比history,稍微丑了点,带个#,因为服务器不会管#后面的内容(根本不会发给服务器),所以不存在404的问题
hash主要就是一个事件,hashchange,直接上demo就好
<body> <p>随机生成的数字是: <span id="num"></span></p> <button onclick="random()">随机生成</button> <script> function random () { var num = parseInt(Math.random() * 100) document.getElementById('num').innerHTML = num window.location.hash = "num=" + num } window.addEventListener('hashchange', function (e) { var str = e.newURL.split('#')[1] document.getElementById('num').innerHTML = str.split('=')[1] }) </script>
以上是前端实现路由的常见的2种方式