基于 jQuery 用两个函数共约 10 行代码做了一个很像 Mithril.js 的前端框架 (非标题党) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
SuperMild
5.49D
V2EX    分享创造

基于 jQuery 用两个函数共约 10 行代码做了一个很像 Mithril.js 的前端框架 (非标题党)

  •  3
     
  •   SuperMild
    ahui2016 2021-03-04 09:51:30 +08:00 4072 次点击
    这是一个创建于 1682 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    大概一个月前看到一个 v 友发贴 ( https://v2ex.com/t/750181 ), 我第一次了解到 Mithril.js 这个框架,看了一下觉得不错,就打算用来改写自己一个小网站的前端页面。

    但使用过程中遇到一个小 bug 解决不了,也可能是我使用不当,具体原因不重要,总之结果是我烦了并且突然灵光一闪想到用 jQuery 也能像 Mithril 一样写网页,就试一了下,一试发现真的可以。

    为什么要模仿 Mithril ?

    • 在使用 jQuery 写小项目的时候,通常习惯写一部分 HTML, 然后再写 js 去操作 DOM, 但这样做不方便做组件。
    • 模仿了 Mithril 之后,完全不写 HTML, 一切都是 js, 因此非常轻松实现组件化,并且实际效果非常好,组件可以相互交流、可以嵌套、可以复用,在下面我会给出具体的示例。

    代码

    基于 jQuery, 再加上以下两个小函数,就是全部代码了。后面我会给出具体的使用示例。

    // 函数名 m 来源于 Mithril, 也可以理解为 make 的简称,用来创建一个元素。 function m(name) { if (jQuery.type(name) == 'string') { return $(document.createElement(name)); } return name.view(); } // 函数名 cc 意思是 create a component, 用来创建一个简单的组件。 function cc(name, id, elements) { if (!id) id = '' + Math.round(Math.random() * 100000000); const vnode = m(name).attr('id', id); if (elements) vnode.append(elements); return {id: '#'+id, raw_id: id, view: () => vnode}; } 

    简单示例 (与 Mithril 对比)

    Mithril 创建一个 component 是这样:

    const Hello = { view: () => m("div", [ m("h1", {class: "title"}, "My first app"), m("button", "A button"), ]) } 

    而使用这个框架(以下简称 mj.js )创建一个 component 有两种方法,一是这样:

    const Hello = { view: () => m('div').append([ m('h1').attr({class: 'title'}).text('My first app'), m('button').text('A button'), ]) } 

    也可以这样:

    const Hello = cc('div', 'hello', [ m('h1').attr({class: 'title'}).text('My first app'), m('button').text('A button'), ]); 

    可见,与 Mithril 的写法非常相似,同时又完全是 jQuery 的基本操作,只要会写 jq, 就完全没有学习难度。

    三个完整的例子

    Hello World

    Get User List

    uglynotes

    结语

    本框架虽然没啥技术含量,但真的好用,特别适合小项目,尤其是如果用过 Mithril.js 或习惯使用 jQuery, 可零学习成本获得一种前端解决方案,多一个选项。比其他框架易学,比 HTML + jQuery 的老办法更容易组织代码。

    项目仓库: https://github.com/ahui2016/mj.js

    第 1 条附言    2021-03-05 20:50:46 +08:00
    我发现大家全都只看重函数 m, 但其实函数 cc 反而是更重要的,它是函数之间互相交流的重点所在,希望大家看看第二个例子 get user list 代码中我写的备注。
    第 2 条附言    2021-05-07 22:06:22 +08:00

    再补充一个例子: mj.js + bootstrap 搭配使用方法 https://github.com/ahui2016/localtags/blob/main/public/home.html

    19 条回复    2021-03-05 20:56:14 +08:00
    tadebao
        1
    tadebao  
       2021-03-04 10:22:18 +08:00
    妙啊
    tikazyq
        2
    tikazyq  
       2021-03-04 10:27:25 +08:00   2
    妈妈不好了,对面那口棺材跳尸了!它似乎还在喊 “前端兴,JQ 王”!
    Austin2035
        3
    Austin2035  
       2021-03-04 10:29:39 +08:00
    Jquery! 永远滴神!
    Austin2035
        4
    Austin2035  
       2021-03-04 10:30:06 +08:00
    @lookcos jQuery
    Sunyanzi
        5
    Sunyanzi  
       2021-03-04 10:44:34 +08:00
    刚巧路过看到 ... 我觉得如果只是这样的话何必用到 jQuery ...

    我自己在用的有类似功能的代码如下 ... 也写了和你一样的示例 ...

    i.imgur.com/tY6tJYm.png

    优势是纯原生无任何依赖且使用时的语法更简单 ... 劣势是实现的代码超过十行了 ...

    名字的话 ... 既然你叫 m 那我叫 m2 好了 ... 一个不太成熟的小玩具供参考 ...
    gaoryrt
        6
    gaoryrt  
       2021-03-04 10:51:44 +08:00
    SuperMild
        7
    SuperMild  
    OP
       2021-03-04 11:06:04 +08:00
    @Sunyanzi jQuery 方便呀,后续组件需要发生变化的时候,addClass, css, show, hide 等等一大堆函数用起来太舒服了,原生 js 要多打很多字母。
    SuperMild
        8
    SuperMild  
    OP
       2021-03-04 11:12:11 +08:00
    @gaoryrt 虽然类似,但侧重点不同,你的工具生成 html 比我的方便、强大,但似乎不关心生成后的操作,而我的组件可以拥有自己的 method, 组件这宰也可以互相交流。
    SuperMild
        9
    SuperMild  
    OP
       2021-03-04 11:13:29 +08:00
    组件这宰 -> 组件之间
    oott123
        10
    oott123  
       2021-03-04 11:47:55 +08:00
    关于“生成元素”这个话题,我喜欢使用 crel : https://www.npmjs.com/package/crel
    当然这和楼主分享的并非一回事,只是顺便推荐~
    Shook
        11
    Shook  
       2021-03-04 12:21:27 +08:00
    @Sunyanzi 这个很酷,学习了
    ai277014717
        12
    ai277014717  
       2021-03-04 13:58:26 +08:00
    隐藏着 id 冲突的 bug 。
    brookepe
        13
    brookepe  
       2021-03-04 14:06:30 +08:00
    @SuperMild 按照你的思路 我加上了一些自己的想法 希望能给个 star
    {gayhub}/brooke1220/jquery.template
    SuperMild
        14
    SuperMild  
    OP
       2021-03-04 18:49:49 +08:00
    @ai277014717 id 问题可根据实际情况改用更小冲突的方法
    SuperMild
        15
    SuperMild  
    OP
       2021-03-04 18:51:48 +08:00
    @brookepe 已 star, 我本意也是抛砖引玉,提供一个思路,大家各自魔改着用~
    brookepe
        16
    brookepe  
       2021-03-04 19:52:44 +08:00
    @SuperMild 我把路由也加上了 /笑哭
    SuperMild
        17
    SuperMild  
    OP
       2021-03-04 20:45:24 +08:00
    @brookepe 路由好评呀
    charten
        18
    charten  
       2021-03-05 14:34:27 +08:00
    我也再写一个类似的,只不过我就直接用 jsx 写然后用 babel 转,比如
    const Hello = {
    view:()=><div><h1 class="title">My first app</h1><button>A button</button></div>

    }
    SuperMild
        19
    SuperMild  
    OP
       2021-03-05 20:56:14 +08:00
    @charten 如果使用 jquery, 就不需要 babel 了,html 是可以直接内嵌的,比如

    const Hello = {
    view:()=> $('<div><h1 class="title">My first app</h1><button>A button</button></div>')
    }

    但大家都误解了我这个东西,它的重点不是生成 html,而是组件与组件之间的交流,在生成 html 之后,组件还能互相交流。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     999 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 18:40 PVG 02:40 LAX 11:40 JFK 14:40
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86