Ruby's Louvre

每天学习一点点算法

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

webpack+avalon+mmState打包方案

终于到讲授如何整合avalon社区这个最强大的组件,基于状态机的路由系统了!

基于状态机的路由系统,据我所知,目前世界上只有三款,angular社区的ui-router, 网易出品的stateman, avalon社区的mmState!

mmState最初是我写的,基于mmRouter上扩展出来,到0.4版时只有400行,后来经过我同事参考ui-router,迅速爆涨到1000行,满足各方面的需求(这其中,社区上也有不少人贡献代码)。因此现在让我重拾mmState的源码,我也几乎看不懂。。。。

之前mmRouter 有一个小BUG,切换视图时会执行两次回调,这个我修了不小心又引发mmState不可用,因此本例请使用最新的0.9版。

mmState 0.9的下载地址

avalon则还是建议使用1.4.*或1.5.*的最新版本

我们沿着上一篇项目的目录,这次要将mmState, mmPromise都要拷贝过来!

现在目录变成这个样子:

我们看一下这个页面吧(state.html)

<!DOCTYPE html>
<html>
    <head>
        <title>mmState组件</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
        <script src="dist/common.js"></script>
        <script src="dist/state.js"></script>
 
    </head>
    <body ms-controller="test">
        <ul>
            <li><a href="#!/aaa">aaa</a></li>
            <li><a href="#!/bbb">bbb</a></li>
            <li><a href="#!/aaa/555">aaa.son</a></li>
            <li><a href="#!/bbb/111">bbb.son</a></li>
        </ul>
        <div ms-view></div>
    </body>
</html>

这个东西只要改改就是一个经典的后台系统,不过我目前不想把示例搞得这么复杂。以后会呈上更好的东西。

我们看一下其主JS文件,里面用avalon.state定义了4个状态对象

var avalon = require("avalon")
require("./mmRouter/mmState")
var vm = avalon.define({
    $id: "test",
    args: ""
});
 
avalon.state("aaa", {
    url: "/aaa",
    views: {
        "": {
            template: "<div>1111<div ms-view=""></div></div>"
        }
    }
}).state("bbb", {
    url: "/bbb",
    views: {
        "": {
            template: "<div>2222<div ms-view=""></div></div>"
        }
    }
}).state("aaa.son", {
    url: "/:bbb",
    views: {
        "": {
            template: "这是子级{{args}}"
        }
    },
    onEnter: function (a) {
        vm.args = a
    }
}).state("bbb.son", {
    url: "/:bbb",
    views: {
        "": {
            templateProvider: function () {
                return new Promise(function (rs) {
                    require.ensure([], function (tt) {
                        rs(require("text!./statetemp.html"))
                    })
                })
            }
        }
    },
    onEnter: function (a) {
        vm.args = a
    }
})
 
avalon.history.start();
avalon.router.navigate("aaa") //默认打开aaa状态
 
avalon.scan(0, vm)

每一个状态对象都有它自己的名字,对应的URL匹配规则,还有views对象。views对象有一个template或templateProvider属性,其实在实际项目中,我偿都应该使用templateProvider,返回一个Promise对象,在Promise里面用上节提到的require.ensure异步加载视图。

如果想了解更详细的用法,可见这里

state.js还依赖一个页面模板,statetemp.html

<b>这是通过异步加载的{{args}}</b>

最后我们在webpack.config.js里加一行代码,指明入口文件

var webpack = require("webpack");
 
var path = require("path");
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
 
module.exports = {
    entry: {
        index: './dev/index', //我们开发时的入口文件
        router: './dev/router',
        router2: './dev/router2',
        ensure: './dev/ensure',
        state: './dev/state'
    },
    output: {
        path: path.join(__dirname, "dist"),
        filename: "[name].js",
        publicPath:"dist/", //给require.ensure用
        chunkFilename: "[name].chunk.js"//给require.ensure用
    }, //页面引用的文件
     
    module: {
        loaders: [
            {test: /\.css$/, loader: 'style-loader!css-loader'}
        ],
        preLoaders: [
            {test: /\.js$/, loader: "amdcss-loader"}
        ]
    },
    plugins: [commonsPlugin],
    resolve: {
        extensions: ['.js', "", ".css"],
        alias: {
            jquery: path.join(__dirname, 'dev/jquery/jquery.js'),
            avalon: path.join(__dirname, 'dev/avalon/avalon.shim'), //在正常情况下我们以CommonJS风格引用avalon,以require('avalon')
            '../avalon': path.join(__dirname, 'dev/avalon/avalon.js')//由于oniui都以是../avalon来引用avalon的,需要在这里进行别名
        }
    }
}

然后执行webpack就能看到效果

大家仔细一看的话,其实这代码早是出奇的少,比angular的少许多,许多操作都是我们框架默认帮你处理好,所以我本人认为其友好度与易用性远胜于ui-router。用好mmState+webpack能迅速为大家搭建一个SPA应用,无论是后台还是手机端,你能享受到MVVM的好处。

如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码

posted on   司徒正美  阅读(6221)  评论(4编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
历史上的今天:
2011-11-25 node.js 动态执行脚本
2010-11-25 mass.query v2 发布
2009-11-25 IE6的getElementById bug
点击右上角即可分享
微信分享提示