路由是什么?

路由器是用来分发请求的。

html:

  1. <body>
  2. <a href="#1">go to 1</a>
  3. <a href="#2">go to 2</a>
  4. <a href="#3">go to 3</a>
  5. <a href="#4">go to 4</a>
  6. <div id="app"></div>
  7. <div id="div1" style="display:none">1</div>
  8. <div id="div2" style="display:none">2</div>
  9. <div id="div3" style="display:none">3</div>
  10. <div id="div4" style="display:none">4</div>
  11. </body>
  12. <script src="src/index.js"></script>

index.js

  1. console.log(window.location.hash) //打印#几
  2. let number = window.location.hash.substr(1) //取#号后面的部分
  3. let div = document.querySelector(`#div${number}`) //根据id获取元素
  4. let app = document.querySelector("#app")
  5. div.style.display = "block" //渲染界面
  6. if(app) app.appendChild(div) //展示界面
  7. window.addEventListener('hashchange',()=>{
  8. console.log('hash 变了')
  9. const number2 = window.location.hash.substr(1)
  10. const div2 = document.querySelector(`#div${number2}`) //根据id获取元素
  11. let app2 = document.querySelector("#app")
  12. div2.style.display = "block"
  13. app2.children[0].style.display = "none"
  14. document.body.appendChild(app2.children[0])
  15. app2.appendChild(div2)
  16. })

优化代码

如果url里没有写#号及后面数字,会报错。所以需要默认路由。
如果url里#号后面没有写正确的路由跳转,就需要保底路由/404路由来解决报错。

  1. function route(){
  2. let number = window.location.hash.substr(1)
  3. let app = document.querySelector("#app")
  4. number = number || 1
  5. let div = document.querySelector(`#div${number}`)
  6. if(!div){
  7. div = document.querySelector("#div404")
  8. }
  9. div.style.display = "block"
  10. if(app.children.length > 0){
  11. app.children[0].style.display = "none"
  12. document.body.apendChild(app.children[0])
  13. }
  14. app.appendChild(div)
  15. }
  16. route()
  17. window.addEventListener("hashchange",()=>{
  18. console.log("hash 变了")
  19. route()
  20. })

路由表

为什么url的#号后面一定要写div几呢!hash和div的对应关系,我希望能自定义。

  1. //路由表开始
  2. const div1 = document.createElement('div')
  3. div1.innerHYML = '1'
  4. const div2 = document.createElement('div')
  5. div2.innerHYML = '2'
  6. const div3 = document.createElement('div')
  7. div3.innerHYML = '3'
  8. const div4 = document.createElement('div')
  9. div4.innerHYML = '4'
  10. const routeTable = {
  11. '1':div1,
  12. '2':div2,
  13. '3':div3,
  14. '4':div4
  15. }
  16. //路由表结束
  17. function route(){
  18. let number = window.location.hash.substr(1)
  19. let app = document.querySelector('#app')
  20. number = number || 1
  21. //
  22. let div = routeTable[number.toString()] //使用路由表
  23. ...
  24. ...
  25. }

嵌套路由/子路由

  1. //路由表开始
  2. const div1 = document.createElement('div')
  3. div1.innerHYML = '1'
  4. const div2 = document.createElement('div')
  5. div2.innerHYML = '2'
  6. const div3 = document.createElement('div')
  7. div3.innerHYML = '3'
  8. const div4 = document.createElement('div')
  9. div4.innerHYML = '4'
  10. const routeTable = {
  11. '1':div1,
  12. '2':div2,
  13. '3':div3,
  14. '4':div4
  15. }
  16. //路由表结束
  17. //子路由表开始
  18. const div11 = document.ceeateElement('div')
  19. div11.innerHTML = '1.1'
  20. const div12 = document.ceeateElement('div')
  21. div12.innerHTML = '1.2'
  22. const route1Table = {
  23. '1/1':div11,
  24. '1/2':div12
  25. }
  26. //子路由表结束 子路由,访问url时这样写:#1/1

hash、history、memory模式

hash,任何情况下都可以用hash模式,缺点是SEO不友好,因为服务器收不到#号及后面的内容。
history,后端将所有前端路由都渲染同一页面,但不能是404页面。例如都渲染为主页。缺点是IE8下不支持。

history

  1. ...省略号,上方是路由表
  2. function route(container){
  3. let number = window.location.pathname //是路径名,以/开头
  4. console.log("number:" + number)
  5. number = number || '/1'
  6. //获取界面
  7. let div = routeTable[number.toString()]
  8. if(!div){
  9. div = document.querySelector("#div404")
  10. }
  11. div.style.display = "block"
  12. //展示界面
  13. container.innerHTML = ""
  14. container.appendChild(div)
  15. }
  16. const allA = document.querySelectorAll("a.link")
  17. for(let a of allA){
  18. a.addEventListener("click",e=>{
  19. e.preventDefault()
  20. const href = a.getAttribute("href")
  21. window.history.pushState(null,`page ${href}`,href)
  22. //通知
  23. onStateChange(href)
  24. })
  25. }
  26. route(app)
  27. function onStateChange(){
  28. console.log('state 变了')
  29. route(app)
  30. }

memory

用对象来存储,而不是像hash和history一样将要去的地方写在url中。例如用localStorage。
适合非浏览器,比如app。
缺点是没有用url。因为将url复制给别人,别人打开时就是默认的页了。

资料来源:饥人谷