zoukankan      html  css  js  c++  java
  • 前端神器avalonJS入门(三)

    本章将介绍如何使用avalon来实现前端路由功能。

    我们需要用到两个avalon路由配套模块—— mmHistory.js 和 mmRouter.js 。其中mmHistory是用于历史管理,它会劫持页面上所有点击链接的行为,当这些链接是以 #/ 、#!/ 开头,就尝试匹配路由规则,阻止页面刷新(通过hash方式或HTML5的replaceState方式)。mmRouter是给我们定义路由规则,路由规则可以更精细地指定每个参数(param)的匹配规则,如果符合就执行对应的回调,如果不符合,就进入error回调。

    关于该路由系统更具体的描述,可以查阅这里

    作为示例,我们打算制作一个网站的 “用户中心” 页面,其中左侧为导航列表,右侧为受左侧列表控制的内容显示区域:

    该“用户中心”页面有这么几个要求:

    ⑴ 页面不跳转,仅做局部(即内容区域部分)刷新;

    ⑵ 可以通过不同的url进入对应的页面(即内容区域显示对应的内容);

    ⑶ 浏览器能记住url状态,比如从“账户详情”点入“我要充值”页面,然后再点击浏览器返回按钮,可以正确回到“账户详情”页面。

    由于不是石器时代,自然不会再选择iframe这种内耗高、不友好的元素来架构页面(而且iframe也实现不了后面两个需求呀)。那么我们会很快联想到Ajax技术,这个想法很本质,不过单纯的Ajax也没办法达到我们的要求,所以才需要引入开头提到的两个avalon路由模块。

    我们可以先写出简单的页面原型:

    index.html:

    复制代码
    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title>账户中心</title>
        <link rel="stylesheet" href="css/user.css">
        <script src="js/lib/require.js" type="text/javascript" data-main="js/page/user"></script>
    </head>
    <body ms-controller="user" class="ms-controller">
    <script type="text/javascript">
        //这里给后端提供数据接口
        var conf = {
            username: {"id": "11", "name": "VaJoy"}
        }
    </script>
    <header>
        <span>{{username.name}}你好,欢迎来到账户中心</span>
    </header>
    <nav>
        <ul>
            <li><a href="#!/index">我的首页</a></li>
            <li><a href="#!/detail">账户详情</a></li>
            <li><a href="#!/recharge">我要充值</a></li>
        </ul>
    </nav>
    <article>
        内容...
    </article>
    </body>
    </html>
    复制代码

    user.js:

    复制代码
    require.config({
        baseUrl: 'js/lib/', 
        paths:{   
            avalon: 'avalon',
            domReady:'domReady',
            mmHistory: 'mmHistory',
            mmRouter: 'mmRouter',
            jquery: 'jq'
        },
        shim:{
            avalon: { exports: "avalon" },
            mmHistory:{ deps: ['avalon']},
            mmRouter:{ deps: ['avalon']}
        }
    });
    
    require(['avalon',"domReady!"], function() {
        var vm = avalon.define({
            $id: "user",
            username:conf.username
        });
        avalon.scan();
    });
    复制代码

    user.css:

    复制代码
    body,html{padding: 0;margin:0;background: #EEE;}
    .ms-controller{visibility: hidden;}
    header{height: 50px;background: white;}
    header>span{display:block;padding: 16px;}
    nav{position: absolute;left:0;margin-top:50px; 200px;}
    nav>ul>li{margin-top: 12px;}
    nav>ul>li>a{text-decoration: none;color:blue;}
    nav>ul>li>a:hover{color:red;}
    article{padding: 15px;margin-left:200px;min-height: 600px;background: white;}
    复制代码

    运行结果如下:

    接着我们要新建三个页面——mine.html、detail.html 和 recharge.html ,分别对应“我的首页”、“账户详情” 和 “我要充值” 的右侧内容,咱在里面随便写点内容意思意思即可,比如mine.html我就写了一句话:

    接着我们默认先把mine.html引入到index.html中,这里我们借助avalon的 ms-include-src 接口,修改下index.html:

    复制代码
    <nav>
        <ul>
            <li><a href="#!/index">我的首页</a></li>
            <li><a href="#!/detail">账户详情</a></li>
            <li><a href="#!/recharge">我要充值</a></li>
        </ul>
    </nav>
    <article ms-include-src="pageUrl"> <!--这里使用ms-include-src接口,它会引入pageUrl属性所对应的文件-->
    </article>
    复制代码

    接着修改 user.js的部分:

    复制代码
    require(['avalon',"domReady!"], function() {
        var vm = avalon.define({
            $id: "user",
            username:conf.username,
            pageUrl:"mine.html"  //默认为mine.html
        });
        avalon.scan();
    });
    复制代码

    运行如下:

    接着是时候让 mmHistory.js 和 mmRouter.js 发挥它们的作用了,我们修改下user.js的部分代码:

    复制代码
    require(['mmHistory','mmRouter',"domReady!"], function() {
        var vm = avalon.define({
            $id: "user",
            username:conf.username,
            pageUrl:"mine.html"  //默认为mine.html
        });
        function callback() {
            if(this.path==="/index"){
                vm.pageUrl="mine.html";
            }else {
                var path_tail = this.path.replace(///, "");
                vm.pageUrl = path_tail + ".html";  //动态修改pageUrl属性值
            }
        }
        avalon.router.get("/*path", callback); //劫持url hash并触发回调
        avalon.history.start(); //历史记录堆栈管理
        avalon.scan();
    });
    复制代码

    注意由于在 require.config 的 shim 中我们已经定义了 mmHistory.js 和 mmRouter.js 是依赖于avalon的,故此处无须再引入avalon模块,requireJS执行该代码段之前会先加载好avalon的。

    我们通过这两行代码执行了路由和历史记录的管理:

        avalon.router.get("/*path", callback); //劫持url hash并触发回调
        avalon.history.start(); //历史记录堆栈管理

    其中router.get() 的第一个参数表示路由匹配规则,比如这里的“/*path”表示匹配全部路径,匹配到了就触发回调callback函数。

    更多的匹配规则我们可以直接在  mmRouter.js 中查看注释信息:

    router.get() 在触发callback前会生成一个this.path属性供callback调用(你也可以给回调函数定义一个参数,其默认值等同与path),其值为当前匹配到的路径,比如当url后缀变成 #!/recharge 的时候,this.path的值为匹配到的"/recharge" 。了解了这个之后,callback 函数也很好理解了:

    复制代码
        function callback() {
            if(this.path==="/index"){
                vm.pageUrl="mine.html"; //如果url后缀变成"#!/index",则pageUrl为“mine.html”
            }else {
                var path_tail = this.path.replace(///, ""); //去掉this.path值的第一个斜杠
                vm.pageUrl = path_tail + ".html";  //动态修改pageUrl属性值
            }
        }
    复制代码

    这时候的运行结果如下所示:

    自此便实现了我们的需求。但是这样还不够完美——每个页面的样式咋处理呢?

    我们可以直接在页面上写<style>标签,或者直接写个<link>引入外部样式文件,但前者不好维护,后者毕竟不是插入到head中的不太规范。那么我们能否也用requireJS模块化动态引入样式文件呢?答案是肯定的,不过得借助于其组件css.js

    以“账户详情”(detail.html)为例,我们创建一个detail.css文件,里面设置 .detail{color:red;}。

    先确保require.config中的paths里加上了该组件:

    复制代码
        paths:{   //这里配置的地址,都是相对于上方的baseUrl的
            avalon: 'avalon',
            domReady:'domReady',
            mmHistory: 'mmHistory',
            mmRouter: 'mmRouter',
            css: 'css'  //加上css.js
        }
    复制代码

    然后修改detail.html页面内容:

    复制代码
    <section ms-controller="detail" class="detail ms-controller">
        哟哟哟,这里是详情页面,{{username.name}}你好
    </section>
    <script>
        require(['avalon','css!../../css/detail.css'], function(){
        //下面的其实建议写成一个模块detail.js然后由require引入
            avalon.define({
                $id: "detail",
                username: conf.username
            });
            avalon.scan();
        })
    </script>
    复制代码

    “css!/XXX.css” 是css.js的写法,注意以"css!"开头即可。

    运行结果如下:

    以上便是avalon前端路由的简单实现,本章的示例代码可以从这里下载。

    后续章节可能会开始写一写avalon的API。共勉~

  • 相关阅读:
    JeePlus:代码生成器
    JeePlus:API工具
    Java实现 洛谷 P1023 税收与补贴问题
    Java实现 洛谷 P1023 税收与补贴问题
    Java实现 洛谷 P1023 税收与补贴问题
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
    Java实现 洛谷 P1328 生活大爆炸版石头剪刀布
  • 原文地址:https://www.cnblogs.com/cymbidium/p/5341404.html
Copyright © 2011-2022 走看看