js有没有什么方法可以实现history路由?

公司现在有一个这样的网页

image.png

不是后台管理, 没有用到angular和vue等, 现在每一一个菜单都对应一个页面
总计有20多个菜单, 创建20多个页面, 每个页面公共代码都要从头到尾复制一遍, 相当麻烦

现在需要进行封装
我这里就直接上小demo了

index.html


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title></title>
        <link rel="stylesheet" href="/library/font-awesome/6.0.0/css/all.min.css">
        <link rel="stylesheet" href="/library/mdb-free/4.20.0/css/bootstrap.min.css">
        <link rel="stylesheet" href="/library/mdb-free/4.20.0/css/mdb.min.css">
    </head>
    <body>
        
        <div id="route-view"></div>
        
        <script src="/library/mdb-free/4.20.0/js/jquery.min.js"></script>
        <script src="/library/mdb-free/4.20.0/js/popper.min.js"></script>
        <script src="/library/mdb-free/4.20.0/js/bootstrap.min.js"></script>
        <script src="/library/mdb-free/4.20.0/js/mdb.min.js"></script>
    </body>
</html>

现在我有一个全局的html文件两个子页面

demoa.html


<h1>demo-a</h1>

demob.html


<h1>demo-b</h1>

image.png

需求 : 根据访问路径的不同, <div id="route-view"></div>里面呈现不同的html, 公共部分不变

例如
(前缀http://127.0.0.1:9000是服务器的默认路径)
访问http://127.0.0.1:9000/pages/t...
需要呈现的html如下


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title></title>
        <link rel="stylesheet" href="/library/font-awesome/6.0.0/css/all.min.css">
        <link rel="stylesheet" href="/library/mdb-free/4.20.0/css/bootstrap.min.css">
        <link rel="stylesheet" href="/library/mdb-free/4.20.0/css/mdb.min.css">
    </head>
    <body>
        
        <div id="route-view"><h1>demo-a</h1></div>
        
        <script src="/library/mdb-free/4.20.0/js/jquery.min.js"></script>
        <script src="/library/mdb-free/4.20.0/js/popper.min.js"></script>
        <script src="/library/mdb-free/4.20.0/js/bootstrap.min.js"></script>
        <script src="/library/mdb-free/4.20.0/js/mdb.min.js"></script>
    </body>
</html>

同样访问b.html, route-view加载demo-a, 这样子就不用每个页面写全局样式了
?有没有什么方法用js可以实现?

阅读 1.7k
1 个回答

没太看懂,需求是?

P.S. vue-router 之类的其实并不是只能用在 vue 里,二者是解耦的;jQuery 项目也可以用 vue-router,只是什么组件注入之类的玩意儿就没有了而已。


【针对问题补充】

明白了,其实用 vue-router 就行,然后用 jquery.ajax 获取一下子页面内容就好。

先占坑,晚点儿写个 demo。


demo 来了。先看一下目录结构(这个你自己按需要调整就好):

image.png

然后是主页面的源码:

<html>
    <head>
        <script src="https://unpkg.com/jquery@3.6.0/dist/jquery.js"></script>
        <script src="https://unpkg.com/vue@2.6.14/dist/vue.js">
            // Vue 需要被引入,要不然 VueRouter 某些方法会抛异常,但实际没有用到 Vue 
            // 你也可以定义一个全局对象叫 Vue、里面包含三个空方法就可以,这样就不用引入整个 Vue 的文件了: 
            //    window.Vue = { component: $.noop, extend: $.noop, mixin: $.noop };
        </script> 
        <script src="https://unpkg.com/vue-router@3.5.4/dist/vue-router.js"></script>
    </head>
    <body>
        <div>
            我是公共部分
            <button id="menuA">切换到 A</button>
            <button id="menuB">切换到 B</button>
        </div>

        <div id="route-view"></div>

        <script>
            const routes = [
                { 
                    name: 'PageA',
                    path: '/a',
                    meta: {
                        template: '/subpages/page-a.html'
                    }
                },
                { 
                    name: 'PageB',
                    path: '/b',
                    meta: {
                        template: '/subpages/page-b.html'
                    }
                },
            ];

            const router = new VueRouter({ mode: 'history', routes: routes });
            
            router.beforeEach(function (to, from, next) {
                // 移除旧页面
                $('#route-view').empty();
                // 加载新页面
                $("#route-view").load(to.meta.template);
                next(true);
            });

            window.$router = router; // 挂到全局,方面后面各个子页面里直接用
        </script>

        <script>
            $('#menuA').on('click', function() { $router.push({ name: 'PageA' }) });
            $('#menuB').on('click', function() { $router.push({ name: 'PageB' }) });
        </script>
    </body>
</html>

两个子页面的源码:

<!-- page-a.html -->
<div>我是页面 A</div>

<!-- page-b.html -->
<div>我是页面 B</div>

运行一下看看效果:

image.png

点一下按钮 A(注意看地址栏、还有页面内容的变化):

image.png

再点一下按钮 B:

image.png

大体思路就是这样,细节部分自己完善吧,比如 loading 啊、加载失败的时候怎么处理啊、还有子页面里可能有额外的 JS/CSS 文件怎么追加到 body 里啊之类的,都没啥复杂的地方,我就不继续写了。

P.S. History Mode 需要后端的 Web Server 调整一下配置,否则你按 F5 刷新就 404 了。具体怎么做看 vue-router/react-router 自己的文档就可以,配置方式是一样的,跟你用不用 Vue/React 没关系。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题