dagger.js:可能是我见过的最简单易用的前端框架了

0b5e31c48aa840e17106bf4c7137ebc0.png

来源 | https://daggerjs.org

今天向大家推荐一款轻量完备且简单易用的开源前端框架dagger.js。

01.什么是dagger.js

dagger.js是一个基于html的描述式单页应用开发框架,通过在页面DOM元素上添加语义化的指令来驱动业务逻辑。从语法特性的角度来说,dagger.js模板+指令的工作方式与Angular/Vue比较接近。

dagger.js采用去组件去api设计,没有对第三方代码或工具的依赖,模型简单,易于理解。与当前的主流前端框架相比,使用者的整体学习和使用成本更低。
使用dagger.js,开发者将无须依赖于:

01).项目构建过程

dagger.js工作在浏览器运行时当中。只需要通过script标签引入框架源码(release版本gzip压缩后约20KB)即可轻松创建单页应用程序。dagger.js对项目代码结构是非侵入式的,您可以以极小成本对历史项目(即使是非单页应用程序)进行渐进升级。

02).包管理工具

dagger.js内部实现了一个运行时模块管理器,根据路由配置按需动态加载和解析各类模块,为您的应用程序进行极限瘦身。

03).第三方路由管理工具

dagger.js内置了基于hash的路由管理器。开发者无需引入额外的路由管理类库。

04).数据状态管理工具

dagger.js倡导数据即状态的技术理念。有别于React/Vue等框架单向数据流模型中对于state/prop对象的区分,dagger.js的作用域数据由框架本身进行维护,并具有全域视图响应性,开发者不必为不同组件间的数据状态同步而劳心费神。

02.开发范式

不同于React Hooks和Vue的组合式API方案,dagger.js提供了更加接近原生javaScript开发体验的心智模型。dagger.js没有设计任何框架相关的“语法糖”,开发者编写的脚本代码只是普通的原生javaScript函数。函数定义本身是上下文无关的,其触发时机、调用参数以及副作用完全由调用者(指令)所决定。

dagger.js中不存在组件(Component)实体的概念,指令是串接作用域数据(Model)和页面视图(View)的桥梁。换句话说,在dagger.js中,一切业务逻辑都以指令作为调用入口。某些特定指令可以在执行上下文创建作用域数据,而所有指令都可以作为作用域数据的消费者。指令读取或者修改作用域数据,进而触发依赖收集或者页面视图的响应式更新。

下文中我们将通过示例代码来体验dagger.js的工作模式。

03.创建作用域

在dagger.js中,我们可以通过生命周期指令“+loading”来创建作用域数据:

<div +loading="{ message: 'Hello dagger!' }">
  <!-- 可以在其他指令中访问或者修改message -->
  ...</div>

+loading”指令在宿主元素(div)初始化时由框架触发调用。它的副作用是,当表达式的执行结果是一个平凡对象时,框架将依据此对象在当前上下文创建出新的作用域数据。技术上说,这个作用域数据是指令返回平凡对象的代理对象。
作用域数据在宿主元素被销毁时由框架自动移除,无需开发者手动管理。

04.指令

在dagger.js中,除去生命周期指令之外,还有两种重要的指令类型:控制指令和事件处理指令。

两种指令都可以自由读写在其声明位置可见的作用域数据,但是行为有所不同。

01).控制指令

控制指令在执行过程中会收集参与计算的作用域变量字段,并在指令的依赖项发生变化时动态触发指令重新执行。我们来看一个例子:

<div dg-cloak
  +loading="{ a: 1, b: 2, c: 0, d: 0 }"
  $watch#1="c = a + b"
  $watch#2="d = 2 * c">
    <button +click="a = 1, b = 2">reset</button>
    <input type="number" $value#input="a">
    <input type="number" $value#input="b">
    <br>
    <span>${ c } = ${ a } + ${ b }</span>
    <br>
    <span>${ d } = 2 * (${ c })</span>
</div>

6f221916a72dfe50b042b735c46c4849.gif

演示地址https://codepen.io/dagger8224/pen/JjpJxzq

上例中,我们在div元素上声明了控制指令“$watch”的两个实例。其中编号为“#1”的指令依赖于作用域变量下字段“a”和字段“b”,编号为“#2”的指令依赖于作用域变量下字段“c”。当用户修改“a”或“b”的值时,将首先触发指令“$watch#1”重新计算,更新字段“c”的值。“c”值发生变化后再触发指令“$watch#2”重新计算,进而更新字段“d”的值。

除去“$watch”指令之外,dagger.js还提供了更多语义化的控制指令,我们简单列举下这些控制指令的使用方法:

<input type="checkbox" $checked="checked">

$checked”指令用于绑定宿主元素的选中状态,适用于类型为“radio”和“checkbox”的“input”元素,以及“option”元素。

<div $class="className">...</div>

$class”指令用于将表达式的内容绑定到宿主元素的class属性上。

<div $each="array">...</div>

$each”指令用于循环渲染具有相同视图模板的数组,对象,或者其他可迭代变量。

<div $exist="exist">...</div>

$exist”指令用于切换宿主元素及其子级元素的存在状态。

<div $html="content"></div>

$html”指令用于在宿主元素下动态创建子级元素。

<input type="file" $file="file">
<input type="file" multiple $file="files">

$file”指令用于绑定用户选择的本地文件信息。

<select $selected="selected">
    <option value="1">1</option>
    ...
</select>

$selected”指令用于绑定宿主元素的选中值,适用于类型为“radio”和“checkbox”的“input”元素,以及“select”元素。

<div $style="style">...</div>

$style”指令用于绑定宿主元素的style属性。

<span $text="text"></span>
<span>${ text }</span>

$text”指令用于在宿主元素下动态创建文本内容。大多数情况下,我们也可以使用原地模板字符串(上例第二种方式)来创建动态文本节点,这样更加简单灵活。

<input type="text" $value="message">

$value”指令用于将表达式的内容与input元素的value建立双向数据绑定。

02).事件处理指令

与控制指令相比,事件处理指令的用法更加简单。事件处理指令由用户操作或系统事件触发调用,在执行过程中不会对作用域数据进行依赖收集。我们来看一个例子:

<button +click="alert(message)">click</button>

上例中,button元素上的“+click”指令声明了一个鼠标点击事件处理函数。类似地,您也可以声明其他的原生事件处理指令(+keyup,+mouseenter等等),或者自定义事件处理指令(例如:+custom_event)。
接下来我们来看几个指令的综合示例:

03).指令综合示例1

下面的示例代码演示了生命周期指令“+loading”,“+loaded”,“+unloading”,“+unloaded”,控制指令“$exist”以及事件处理指令“+click”的使用:

<div dg-cloak +loading="{ status: '', exist: true }">
    <button +click="exist = !exist">toggle exist</button>
    <span class="status-span">The status of dynamic span: ${ status }</span>
    <span class="dynamic-span"
      $exist="exist"
      +loaded="status = 'existing'"
      +unloading="status = 'removing'"
      +unloaded="status = 'removed'">
        Some content
    </span>
</div>

点击按钮将切换作用域字段“exist”的值,进而触发声明了“$exist”指令的span元素加载或移除。

9cb44383e7b6b863af99450514f5ca8e.gif

演示地址:https://codepen.io/dagger8224/pen/wvmgRyj

04).指令综合示例2

下面的示例代码演示了控制指令“$each”和“$checked”的使用:

<label $each="[1, 2, 3]">
<input type="checkbox" name="checkbox1" $checked="checked[index]">checkbox${ item }
</label>

切换复选框的勾选状态,作用域变量“checked”字段的内容将随之发生变化,这是双向数据绑定指令的典型用法。

911f84ec3df75b7ec20dec49022bd842.gif

演示地址:https://codepen.io/dagger8224/pen/PoRpROq

各种指令更详细的定义和使用方法参见官方文档:https://daggerjs.org/#/directive/introduction

05.模块

接下来我们一起了解下dagger.js的模块设计。

在dagger.js中,我们把html模板,脚本,层叠样式表等可复用的代码片段统称为模块。dagger.js内部维护了一个运行时模块管理器,开发者通过json格式的配置项注册模块,框架将在应用程序首次加载或页面内路由发生切换时触发模块资源按需动态加载、解析和执行。与作用域数据类似,模块仅在其注册层级及子层级生效,避免对全局作用域造成污染。您可以根据业务需求灵活配置模块的组合方式(每一个组合方案构成一个名空间)来实现代码复用。我们来看一个模块配置项的示例:

<script type="dagger/configs"> 
{ 
"script": "https://codepen.io/dagger8224/pen/NWyVxwx.js", 
"style": "https://codepen.io/dagger8224/pen/NWyVxwx.css", 
"template":  { 
   "uri": "#template", 
   "style": "style" 
    } 
 }
</script>

上面的配置项中,我们注册了一个名为“script”的脚本模块,一个名为“style”的样式模块,和一个名为“template”的模板模块,并将样式模块的作用范围限定为模板模块内部。

演示地址:https://codepen.io/dagger8224/pen/rNJrzzj

06.路由

作为一个完备的单页应用开发框架,dagger.js内置了基于浏览器hash的路由管理器。当页面路由发生切换时,根作用域下“$router”对象的内容将同步变化,进而驱动页面视图产生响应式更新(需要配合“$html”控制指令使用)。我们来看一个示例:

36c7d62d2aa38f9e2ec19f9303fb857e.gif

上例中,当路由从“root”切换至“parent1”之后,页面内容将发生切换。

演示地址:https://codepen.io/dagger8224/pen/zYRQrwP‍‍‍‍‍‍‍‍‍

路由对象的字段内容可以在下面的示例中查看:

50153b997e9e88bfc0e3264afcddd469.gif

演示地址:https://codepen.io/dagger8224/pen/PoQBovd

07.渲染性能

dagger.js并未采用虚拟DOM方案,而是通过细粒度的指令执行来实现页面视图增量更新。在js-framework-benchmark测试场景中,其综合运行时性能与React17版本相当。

08.未来计划

dagger.js目前已经在多家公司的B端管理系统当中得到应用。在未来,我们计划围绕框架持续建设周边生态,通过开源方式对框架进行推广运营,让更多的前端开发者有机会了解和使用dagger.js。

09.总结

dagger.js是一个轻量级无依赖的描述式前端开发框架,与主流框架相比,具有更低的学习和使用成本。用户仅需了解上文中介绍的指令,模块与路由的相关概念和用法,就可以快速上手使用dagger.js构建单页应用程序。

以上是对dagger.js主要功能特性的概要介绍。更多信息请查看官方文档:https://daggerjs.org/

github地址:https://github.com/dagger8224/dagger.js

更多示例截图

01).three.js

81180d3d9fb0651fe87c543367807324.gif

演示地址:https://codepen.io/dagger8224/pen/QWmwaLq

02).3D Carousel

f6c11d0cc43e67281330a3520e729952.gif

演示地址:https://codepen.io/dagger8224/pen/JjLRbmz

03).Tesla

6b2c32f53f17e33809c8ca653f2052ea.gif

演示地址:https://codepen.io/dagger8224/pen/RwMGvPv?editors=1010

04).color picker

00dca22d94b92ec274e1d738ce4dbcc9.gif

演示地址:https://codepen.io/dagger8224/pen/vYRmGJp?editors=1010

05).progress bar

1ac35d10f9467880ba9474f92a95c2e4.gif

演示地址:https://codepen.io/dagger8224/pen/dympJXz?editors=1010

06).text animation

b9552ed479579aaab3d6e2128b992c63.gif

演示地址:https://codepen.io/dagger8224/pen/JjLXppg

除了以上示例外,您还可以通过我们的codepen进行了解更多它的精彩有趣的案例,地址如下:

 https://codepen.io/dagger8224/pens 

如果您觉得dagger.js有用的话,请记得点赞,分享,转发给您的朋友,也许能够帮助到他,最后,感谢您的阅读,祝编程愉快!

学习更多技能

请点击下方公众号

16bad088f71fb3966b573ffb80d75533.gif

cdeb3fd4f01a8d24490b7f58af72a47b.jpeg

f8eba620f9f3b1eb828e60fb7a08e53c.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dagger是网易杭州研究院QA团队开发的一个轻量级、运行稳定的WebUI自动化测试框架,主要基于Selenium及TestNg可以认为是对Selenium进行二次封装的一个框架(俗称 造轮子 )。之所以把这个轮子开源出来,主要在于经过了公司内部多个项目的实践,也取得了不错的成效,因此,希望开源以后可以对大家有所帮助及参考。 设计理念 Dagger首先是一个WebUI自动化框架,提供了赖以操纵浏览器的一些API。API数量不多,少于20个,但从实践上,已经基本涵盖95%的应用场景了(其余5%比较 个性 的自动化操作一般是封装在业务逻辑层面,有时候甚至会须要hack) Dagger其次是一个测试框架,使用TestNg管理和运行用例,TestNg相关断言内嵌于上述API中。因此,在我们的测试用例里面不应该看到单独的TestNg断言的 Dagger还是一种设计风格:简约。无论是Dagger框架本身还是基于Dagger编写的测试用例,都是十分light及straightforward的,以至于会让人感觉有点土。但实践中,这两者确保了低成本、易用性、可维护性 WebUI自动化从业界看,难推进,易烂尾,原因基本在于:维护成本高、运行速度慢、稳定性差 Dagger专注于WebUI自动化,从技术上克服了速度与稳定问题(下文)。只封装够用的浏览器操作为API,并充分简化/强化这些API,以简约的风格去降低自动化的学习及使用成本。同时,在实践中,我们主要使用Dagger编写冒烟用例、其次是主干用例,少写逻辑复杂功能,不写边边角角功能,让用例也保持清爽(在整个自动化实施过程中,会定期进行用例Review),同样易于后期维护 主要特性 API极少,易于上手,详这里. 提供比较完备的文档,便于快速入门,详这里. 支持单机多浏览器并发执行,大大缩短用例执行时间,详这里 通过修改TestNg源码实现失败用例自动重运行(详这里)由此几乎消除WebUI自动化中常的虚假失败 默认使用Chrome浏览器,原因详这里 失败用例自动截屏 后续工作 加入Flex/Flash自动化支持 如何使用 Dagger十分适合中小型团队从零开始WebUI自动化,这样的话,只须要直接下载整个Dagger代码就行了,Dagger本身都已经配置好了,下载后看一下使用文档就可以直接开始写用例了 也可以把Dagger打成Jar包,导入已有的自动化框架中,详这里 标签:Dagger  自动化测试

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值