基于 jQuery 用两个函数共约 10 行代码做了一个很像 Mithril.js 的前端框架 (非标题党) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
爱意满满的作品展示区。
SuperMild
5.49D

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

  •  3
     
  •   SuperMild
    ahui2016 Mar 4, 2021 4510 views
    This topic created in 1880 days ago, the information mentioned may be changed or developed.

    背景

    大概一个月前看到一个 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

    Supplement 1    Mar 5, 2021
    我发现大家全都只看重函数 m, 但其实函数 cc 反而是更重要的,它是函数之间互相交流的重点所在,希望大家看看第二个例子 get user list 代码中我写的备注。
    Supplement 2    May 7, 2021

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

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

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

    i.imgur.com/tY6tJYm.png

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

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

    }
    SuperMild
        19
    SuperMild  
    OP
       Mar 5, 2021
    @charten 如果使用 jquery, 就不需要 babel 了,html 是可以直接内嵌的,比如

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

    但大家都误解了我这个东西,它的重点不是生成 html,而是组件与组件之间的交流,在生成 html 之后,组件还能互相交流。
    About     Help     Advertise     Blog     API     FAQ     Solana     3319 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 74ms UTC 13:15 PVG 21:15 LAX 06:15 JFK 09:15
    Do have faith in what you're doing.
    ubao msn 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