前些天去網易面試,太緊張了結果犯了不少的錯,很多還是簡單的錯。
現在回想起來,還是覺得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種方式