前端路由及两种实现方式

发布时间 2023-11-29 10:20:26作者: Laravel自学开发

路由的概念来源于服务端,在服务端中路由描述的是 URL与处理函数之间的映射关系,当然也会处理不同的URL来展示不同
的视图界面。
随着Ajax的盛行,无刷新交互成为了当下的主流,我们更希望在无刷新的情况下完成不同URL来展示不同的视图界面,即在一
个页面中完成路由的切换(俗称:单页面应用开发SPA),这就是前端路由。
那么如何做到在一个页面中完成URL与UI的映射关系呢?一般我们有两种实现方案:

  1. hash模式
  2. history模式

hash模式

hash模式
hash是 URL中 hash (#) 及后面的那部分,常用作锚点在页面内进行导航,改变 URL中的 hash部分不会引起页面刷新。我们通
过 hashchange 事件来监听 hash值的改变,这样就可以显示不同的UI内容,示例代码如下:

<body>
    <ul>
    <!-- 定义路由 -->
        <li><a href="#/home">home</a></li>
        <li><a href="#/about">about</a></li>
        <!-- 渲染路由对应的 UI -->
        <div id="routerView"></div>
    </ul>
</body>
<script>
window.addEventListener('hashchange', onHashChange)
    onHashChange()
    function onHashChange () {
    switch (location.hash) {
        case '#/home':
        	routerView.innerHTML = 'Home'
        break;
        case '#/about':
        	routerView.innerHTML = 'About'
        break;
    }
}
</script>

history模式

history对象提供了pushState方法和popstate事件,pushState方法可以让URL发生改变但并不会引起页面的刷新,而popstate事件则
用来监听URL改变的值,这样就可以显示不同的UI内容,示例代码如下:

<body>
    <ul>
    	<!-- 定义路由 -->
        <li><a href="/home">home</a></li>
        <li><a href="/about">about</a></li>
        <!-- 渲染路由对应的 UI -->
        <div id="routerView"></div>
    </ul>	
</body>
<script>
    let linkList = document.querySelectorAll('a[href]')
    for(let i=0;i<linkList.length;i++){
        linkList[i].addEventListener('click', function(e){
            e.preventDefault()
            history.pushState(null, '', this.getAttribute('href'))
            onPopState()
        })
    }
    window.addEventListener('popstate', onPopState)
        onPopState()
        function onPopState () {
            switch (location.pathname) {
            case '/home':
            	routerView.innerHTML = 'Home'
            break;
            case '/about':
            	routerView.innerHTML = 'About'
            break;
        }
    }
</script>

注意:以上代码要在服务器环境下运行,才会生效。
这种history模式存在一个问题,那就是当刷新页面的时候就会出现找不到页面的情况,即:Cannot GET /home。这主要是因为
history模式的URL地址跟普通的URL地址没有任何区别,刷新的时候服务器会去找相关的资源,我们在服务器上根本就没有这
个资源,就会出现找不到的现象。
解决这个问题,你需要做的就是在你的服务器上添加一个简单的回退路由。如果 URL不匹配任何静态资源,它应提供与你的
应用程序中的 index.html 相同的页面。漂亮依旧!
下面是nginx服务器实现的示例:

location / {
	try_files $uri $uri/ /index.html;
}

Vue框架给我们提供了一个第三方的路由框架,即:vue-router,官网地址:https://router.vuejs.org/zh/index.html。vue-router提
供了两种路由模式,可自由选择,而且在开发阶段,脚手架还帮我们处理了history找不到页面的情况。