HTML也可以静态编译,损害了复用性
分类:前端技术

React.Component 损害了复用性?

2016/09/07 · 底蕴技能 · binding.scala, data-binding, React, scala.js

本文笔者: 伯乐在线 - ThoughtWorks 。未经笔者许可,防止转发!
接待插足伯乐在线 专栏撰稿者。

本种类的上风流倜傥篇小说《何以ReactJS不切合复杂的前端项目》列举了前端开垦中的各类痛点。本篇文章少将详细查究此中“复用性”痛点。我们将用原生 DHTML API 、 ReactJS 和 Binding.scala 落成同三个须求复用的价签编辑器,然后相比非常多少个标签编辑器哪个达成难度更低,哪个更加好用。

HTML也可以静态编写翻译?

2016/11/30 · HTML5 · 1 评论 · binding.scala, React, 前端

本文作者: 伯乐在线 - ThoughtWorks 。未经小编许可,制止转发!
款待参与伯乐在线 专栏小编。

More than React体系随笔:

《More than React(后生可畏卡塔尔为啥ReactJS不合乎复杂的前端项目?》

《More than React(二卡塔尔React.Component毁伤了复用性?》

《More than React(三)虚拟DOM已死?》

《More than React(四卡塔 尔(英语:State of Qatar)HTML也得以静态编写翻译?》


《More than React》体系的上豆蔻梢头篇作品《虚拟DOM已死?》相比了Binding.scala和别的框架的渲染机制。本篇文章中将介绍Binding.scala中的XHTML语法。

为什么 ReactJS 不适合复杂的前端项目?

2016/08/17 · JavaScript · 15 评论 · React, ReactJS, 前端

正文笔者: 伯乐在线 - ThoughtWorks 。未经我许可,防止转发!
应接参与伯乐在线 专栏编辑者。

《More than React》种类的稿子会一齐分为五篇。本文是首先篇,介绍用ReactJS开荒时蒙受的各个难题。后面四篇文章的每后生可畏篇将会分别详细议论此中贰个主题素材,以至Binding.scala如何消除那么些标题。

《More than React》种类的文章会一同分为五篇。本文是率先篇,介绍用ReactJS开垦时碰到的各种难题。前面四篇小说的每后生可畏篇将会分别详细商讨在那之中叁个标题,以致Binding.scala怎么着解决那几个难题。

标签编辑器的作用必要

在InfoQ的众多稿子都有标签。举例本文的标签是“binding.scala”、“data-binding”、“scala.js”。

假诺你要花销叁个博客系统,你也指望博客作者可以拉长标签。所以你恐怕会提供标签编辑器供博客我选用。

如图所示,标签编辑器在视觉上分为两行。

图片 1

先是行展现已经增添的有所标签,各样标签旁边有个“x”按键能够去除标签。第二行是八个文本框和二个“Add”开关可以把文本框的开始和结果丰裕为新标签。每一遍点击“Add”开关时,标签编辑器应该检查标签是不是曾经增加过,以防再一次增多标签。而在中标加多标签后,还应清空文本框,以便客商输入新的标签。

除了客户分界面以外,标签编辑器还应当提供 API 。标签编辑器所在的页面能够用 API 填入开始标签,也足以调用 API 任何时候增加和删除查改标签。如若客户增加和删除了标签,应该有某种机制布告页面包车型大巴别的一些。

其他前端框架的难点

背景介绍

二零一八年 4 月,作者第二遍在有个别客商的门类中接触到ReactJS 。

自己意识ReactJS要比作者原先用过的AngularJS轻易非常多,它提供了响应式的数据绑定效能,把多少映射到网页上,使笔者得以轻松达成相互影响简单的网站。

唯独,随着笔者更是深刻的采纳ReactJS,笔者发觉用ReactJS编写人机联作复杂的网页很费力。 笔者盼望有生龙活虎种办法,能够像ReactJS相符轻便清除简单难题。此外,还要能轻松消除复杂问题。

于是乎本人把ReactJS用Scala重新写了三个。代码量从近四万行降至了黄金年代千多行。

用那一个框架完结的TodoMVC应用,只用了154行代码。而用ReactJS完毕平等功效的TodoMVC,需要488行代码。

下图是用Binding.scala达成的TodoMVC应用。

图片 2

其风度翩翩框架正是Binding.scala。

背景介绍

二零一八年 4 月,小编先是次在有些顾客的体系中接触到ReactJS 。

本人发掘ReactJS要比笔者原先用过的AngularJS轻易非常多,它提供了响应式的多少绑定成效,把数量映射到网页上,使自个儿得以轻便实现相互影响简单的网址。

但是,随着笔者进一层深入的选择ReactJS,作者发觉用ReactJS编写人机联作复杂的网页非常不方便。
自家盼望有意气风发种方法,能够像ReactJS相仿轻易解决轻巧难题。除此以外,还要能轻易解决复杂难点。

于是乎小编把ReactJS用Scala重新写了四个。代码量从近五万行降低到了风姿洒脱千多行。

用那几个框架达成的TodoMVC应用,只用了154行代码。而用ReactJS落成平等效率的TodoMVC,需要488行代码。

下图是用Binding.scala完成的TodoMVC应用。

本条框架便是Binding.scala。

原生 DHTML 版

率先,小编试着不用别的前端框架,直接调用原生的 DHTML API 来贯彻标签编辑器,代码如下:

JavaScript

<!DOCTYPE html> <html> <head> <script> var tags = []; function hasTag(tag) { for (var i = 0; i < tags.length; i ) { if (tags[i].tag == tag) { return true; } } return false; } function removeTag(tag) { for (var i = 0; i < tags.length; i ) { if (tags[i].tag == tag) { document.getElementById("tags-parent").removeChild(tags[i].element); tags.splice(i, 1); return; } } } function addTag(tag) { var element = document.createElement("q"); element.textContent = tag; var removeButton = document.createElement("button"); removeButton.textContent = "x"; removeButton.onclick = function (event) { removeTag(tag); } element.appendChild(removeButton); document.getElementById("tags-parent").appendChild(element); tags.push({ tag: tag, element: element }); } function addHandler() { var tagInput = document.getElementById("tag-input"); var tag = tagInput.value; if (tag && !hasTag(tag)) { addTag(tag); tagInput.value = ""; } } </script> </head> <body> <div id="tags-parent"></div> <div> <input id="tag-input" type="text"/> <button onclick="addHandler()">Add</button> </div> <script> addTag("initial-tag-1"); addTag("initial-tag-2"); </script> </body> </html>

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;script&gt;
    var tags = [];
 
    function hasTag(tag) {
      for (var i = 0; i &lt; tags.length; i ) {
        if (tags[i].tag == tag) {
          return true;
        }
      }
      return false;
    }
 
    function removeTag(tag) {
      for (var i = 0; i &lt; tags.length; i ) {
        if (tags[i].tag == tag) {
          document.getElementById("tags-parent").removeChild(tags[i].element);
          tags.splice(i, 1);
          return;
        }
      }
    }
 
    function addTag(tag) {
      var element = document.createElement("q");
      element.textContent = tag;
      var removeButton = document.createElement("button");
      removeButton.textContent = "x";
      removeButton.onclick = function (event) {
        removeTag(tag);
      }
      element.appendChild(removeButton);
      document.getElementById("tags-parent").appendChild(element);
      tags.push({
        tag: tag,
        element: element
      });
    }
 
    function addHandler() {
      var tagInput = document.getElementById("tag-input");
      var tag = tagInput.value;
      if (tag &amp;&amp; !hasTag(tag)) {
        addTag(tag);
        tagInput.value = "";
      }
    }
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id="tags-parent"&gt;&lt;/div&gt;
  &lt;div&gt;
    &lt;input id="tag-input" type="text"/&gt;
    &lt;button onclick="addHandler()"&gt;Add&lt;/button&gt;
  &lt;/div&gt;
  &lt;script&gt;
    addTag("initial-tag-1");
    addTag("initial-tag-2");
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
 

为了兑现标签编辑器的功力,笔者用了 45 行 JavaScript 代码来编排 UI 逻辑,外加若干的 HTML <div> 外加两行 JavaScript 代码填入初步化数据。

HTML 文件中硬编码了多少个 <div>。这些<div> 本身并非动态创造的,但能够作为容器,放置任何动态创造的成分。

代码中的函数来会把网页内容动态更新到那一个 <div> 中。所以,假如要在同叁个页面显示四个标签编辑器,id 就能够冲突。由此,以上代码未有复用性。

就算用 jQuery 替代 DHTML API,代码复用还是很难。为了复用 UI ,jQuery 开采者经常必需附加增添代码,在 onload 时扫描整个网页,搜索具备一定 class 属性的成分,然后对那些成分进行纠正。对于复杂的网页,这个 onload 时运营的函数比较轻巧就能冲突,比方一个函数改善了贰个 HTML 成分,平时形成另后生可畏处代码受影响而里边意况错乱。

对HTML的欠缺帮衬

原先我们运用其余前端框架,举个例子Cycle.js 、Widok、ScalaTags时,由于框架不扶植HTML语法,前端程序员被迫浪费大批量光阴,手动把HTML改写成代码,然后稳步调节和测量试验。

哪怕是永葆HTML语法的框架,比方ReactJS,协理情况也很东鳞西爪。

诸如,在ReactJS中,你不可能这样写:

JavaScript

class BrokenReactComponent extends React.Component { render() { return ( <ol> <li class="unsupported-class">不支持 class 属性</li> <li style="background-color: red">不支持 style 属性</li> <li> <input type="checkbox" id="unsupported-for"/> <label for="unsupported-for">不支持 for 属性</label> </li> </ol> ); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class BrokenReactComponent extends React.Component {
  render() {
    return (
      <ol>
        <li class="unsupported-class">不支持 class 属性</li>
        <li style="background-color: red">不支持 style 属性</li>
        <li>
          <input type="checkbox" id="unsupported-for"/>
          <label for="unsupported-for">不支持 for 属性</label>
        </li>
      </ol>
    );
  }
}

前端程序猿必须手动把 classfor 属性替换到 classNamehtmlFor,还要把内联的 style 样式从CSS语法改成JSON语法,代码才具运作:

JavaScript

class WorkaroundReactComponent extends React.Component { render() { return ( <ol> <li className="workaround-class">被迫把 class 改成 className</li> <li style={{ backgroundColor: "red" }}>被迫把体制表改成 JSON</li> <li> <input type="checkbox" id="workaround-for"/> <label htmlFor="workaround-for">被迫把 for 改成 htmlFor</label> </li> </ol> ); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class WorkaroundReactComponent extends React.Component {
  render() {
    return (
      <ol>
        <li className="workaround-class">被迫把 class 改成 className</li>
        <li style={{ backgroundColor: "red" }}>被迫把样式表改成 JSON</li>
        <li>
          <input type="checkbox" id="workaround-for"/>
          <label htmlFor="workaround-for">被迫把 for 改成 htmlFor</label>
        </li>
      </ol>
    );
  }
}

这种开辟方式下,前端工程师纵然能够把HTML原型复制粘贴到代码中,但还亟需大批量改建本领实际运作。比Cycle.js、Widok或许ScalaTags省相连太多事。

主题素材意气风发:ReactJS组件难以在头晕目眩交互作用页面中复用

ReactJS中的最小复用单位是组件。ReactJS的零件比AngularJS的Controller和View 要轻量些。 每一个组件只须要前端开辟者提供二个 render 函数,把 propsstate 映射成网页元素。

这么的轻量级组件在渲染轻巧静态页面时很好用, 可是假使页面有相互,就非得在组件间传递回调函数来处管事人件。

本身就要《More than React(二卡塔 尔(英语:State of Qatar)组件对复用性有剧毒?》中用原生DHTML API、ReactJS和Binding.scala完成同三个亟待复用的页面,介绍Binding.scala怎样轻松达成、轻巧复用复杂的互相逻辑。

主题素材生龙活虎:ReactJS组件难以在纷纭人机联作页面中复用

ReactJS中的最小复用单位是组件。ReactJS的构件比AngularJS的Controller和View 要轻量些。
各样组件只必要前端开采者提供叁个 render 函数,把 propsstate 映射成网页成分。

如此那般的轻量级组件在渲染轻便静态页面时很好用,
只是若是页面有相互,就必需在组件间传递回调函数来处管事人件。

自个儿将要《More than React(二卡塔尔组件对复用性有剧毒?》中用原生DHTML API、ReactJS和Binding.scala达成同叁个亟需复用的页面,介绍Binding.scala如何轻便完毕、轻松复用复杂的互相逻辑。

ReactJS 完毕的标签编辑器组件

ReactJS 提供了足以复用的零部件,即 React.Component 。若是用 ReactJS 完结标签编辑器,大致能够那样写:

JavaScript

class TagPicker extends React.Component { static defaultProps = { changeHandler: tags => {} } static propTypes = { tags: React.PropTypes.arrayOf(React.PropTypes.string).isRequired, changeHandler: React.PropTypes.func } state = { tags: this.props.tags } addHandler = event => { const tag = this.refs.input.value; if (tag && this.state.tags.indexOf(tag) == -1) { this.refs.input.value = ""; const newTags = this.state.tags.concat(tag); this.setState({ tags: newTags }); this.props.changeHandler(newTags); } } render() { return ( <section> <div>{ this.state.tags.map(tag => <q key={ tag }> { tag } <button onClick={ event => { const newTags = this.state.tags.filter(t => t != tag); this.setState({ tags: newTags }); this.props.changeHandler(newTags); }}>x</button> </q> ) }</div> <div> <input type="text" ref="input"/> <button onClick={ this.addHandler }>Add</button> </div> </section> ); } }

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class TagPicker extends React.Component {
 
  static defaultProps = {
    changeHandler: tags =&gt; {}
  }
 
  static propTypes = {
    tags: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
    changeHandler: React.PropTypes.func
  }
 
  state = {
    tags: this.props.tags
  }
 
  addHandler = event =&gt; {
    const tag = this.refs.input.value;
    if (tag &amp;&amp; this.state.tags.indexOf(tag) == -1) {
      this.refs.input.value = "";
      const newTags = this.state.tags.concat(tag);
      this.setState({
        tags: newTags
      });
      this.props.changeHandler(newTags);
    }
  }
 
  render() {
    return (
      &lt;section&gt;
        &lt;div&gt;{
          this.state.tags.map(tag =&gt;
            &lt;q key={ tag }&gt;
              { tag }
              &lt;button onClick={ event =&gt; {
                const newTags = this.state.tags.filter(t =&gt; t != tag);
                this.setState({ tags: newTags });
                this.props.changeHandler(newTags);
              }}&gt;x&lt;/button&gt;
            &lt;/q&gt;
          )
        }&lt;/div&gt;
        &lt;div&gt;
          &lt;input type="text" ref="input"/&gt;
          &lt;button onClick={ this.addHandler }&gt;Add&lt;/button&gt;
        &lt;/div&gt;
      &lt;/section&gt;
    );
  }
 
}
 

以上 51 行 ECMAScript 二〇一六代码达成了一个标签编辑器组件,即TagPicker。即使代码量比 DHTML 版长了一小点,但复用性大大提高了。

设若您不用 ECMAScript 二〇一五 的话,那么代码还团体首领一些,况且亟需管理局部JavaScript 的坑,比方在回调函数中用持续 this

ReactJS 开拓者能够每二二十三日用 ReactDOM.render 函数把 TagPicker 渲染到其它层空间白成分内。其他,ReactJS 框架能够在 stateprops 更换时触发 render ,进而防止了手动改革现成的 DOM。

设若不构思冗余的 key 属性,单个组件内的交互作用 ReactJS 还算壮志未酬。不过,复杂的网页布局往往须要四个零零部件层层嵌套,这种老爹和儿子组件之间的相互影响,ReactJS 就很吃力了。

比如,假若须要在 TagPicker 之外展现全部的竹签,每当客户增加和删除标签,那么些标签也要自动更新。要完结那么些意义,须要给 TagPicker 传入 changeHandler 回调函数,代码如下:

JavaScript

class Page extends React.Component { state = { tags: [ "initial-tag-1", "initial-tag-2" ] }; changeHandler = tags => { this.setState({ tags }); }; render() { return ( <div> <TagPicker tags={ this.state.tags } changeHandler={ this.changeHandler }/> <h3>全体标签:</h3> <ol>{ this.state.tags.map(tag => <li>{ tag }</li> ) }</ol> </div> ); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Page extends React.Component {
 
  state = {
    tags: [ "initial-tag-1", "initial-tag-2" ]
  };
 
  changeHandler = tags =&gt; {
    this.setState({ tags });
  };
 
  render() {
    return (
      &lt;div&gt;
        &lt;TagPicker tags={ this.state.tags } changeHandler={ this.changeHandler }/&gt;
        &lt;h3&gt;全部标签:&lt;/h3&gt;
        &lt;ol&gt;{ this.state.tags.map(tag =&gt; &lt;li&gt;{ tag }&lt;/li&gt; ) }&lt;/ol&gt;
      &lt;/div&gt;
    );
  }
 
}
 

为了能接触页面别的部分更新,作者被迫扩张了三个 21 行代码的 Page 组件。

Page 组件必须完成 changeHandler 回调函数。每当回调函数触发,调用 Page 自己的 setState 来触发 Page 重绘。

从那一个事例,我们能够见到, ReactJS 能够轻松的消除轻松的难点,但碰撞档案的次序复杂、交互作用频仍的网页,完结起来就很麻烦。使用 ReactJS 的前端项目充满了种种 xxxHandler 用来在组件中传递音信。作者参加的某国外客商项目,平均各个组件大概需求传入七个回调函数。假设档期的顺序嵌套深,创建网页时,平日必要把回调函数从最顶层的零构件风度翩翩稀世传入最后面部分的零零部件,而当事件触发时,又供给风度翩翩稀少把事件消息往外传。整个前端项目有超过一半代码都在这么绕圈子。

不相配原生DOM操作

除此以外,ReactJS等部分前端框架,会生成虚构DOM。虚构DOM不可能合作浏览器原生的DOM API ,引致和jQuery、D3等另外库协作时千难万险。举个例子ReactJS更新DOM对象时平时会损坏掉jQuery控件。

Reddit有的是人研讨了那么些难题。他们并未主意,只可以弃用jQuery。小编司的某顾客在用了ReactJS后也被迫用ReactJS重写了大气jQeury控件。

标题二:ReactJS的虚构DOM 算法又慢又不许

ReactJS的页面渲染算法是设想DOM差量算法。

开辟者须求提供 render 函数,根据 propsstate 生成设想 DOM。 然后 ReactJS 框架依照 render 再次来到的伪造 DOM 创立相似构造的实在 DOM.

每当 state 校正时,ReacJS 框架重新调用 render 函数,获取新的虚构 DOM 。 然后,框架会比较上次生成的伪造 DOM 和新的诬捏 DOM 有啥样差距,然后把差别应用到真正DOM上。

如此那般做有两大短处:

  1. 每次 state 更改,render 函数都要生成完全的虚构 DOM. 哪怕 state 退换十分小,render函数也会全部总括一回。假设 render 函数很复杂,这一个过程就白白浪费了无数计量能源。
  2. ReactJS框架比较虚构DOM差距的历程,既慢又轻便出错。举例,固然你想要在有个别 <ul>列表的最上部插入黄金时代项 <li> ,那么ReactJS框架会误感到你改改了 <ul> 的每生龙活虎项 <li>,然后在尾巴部分插入了三个 <li>

那是因为 ReactJS收到的新旧五个虚构DOM之间相互独立,ReactJS并不知道数据源发生了怎么样操作,只可以依据新旧八个虚构DOM来猜测内需实施的操作。 自动的狐疑算法既不许又慢,必须求前端开垦者手动提供 key 属性、shouldComponentUpdate 方法、componentDidUpdate 方法只怕 componentWillUpdate 等方法才干帮忙 ReactJS 框架猜对。

本身将要《More than React(三卡塔 尔(英语:State of Qatar)设想DOM已死?》中相比ReactJS、AngularJS和Binding.scala渲染机制,介绍轻巧品质高的Binding.scala准确数据绑定机制。

标题二:ReactJS的虚构DOM 算法又慢又不许

ReactJS的页面渲染算法是假造DOM差量算法。

开采者必要提供 render 函数,根据 propsstate 生成虚拟 DOM。
然后 ReactJS 框架依照 render 重回的虚构 DOM 创设相同构造的真实性 DOM.

每当 state 校勘时,ReacJS 框架重新调用 render 函数,获取新的设想 DOM 。
接下来,框架会比较上次生成的假造 DOM 和新的虚构 DOM 有如何区别,然后把差别应用到真实DOM上。

如此那般做有两大破绽:

  1. 每次 state 更改,render 函数都要生成完全的伪造 DOM. 哪怕 state 改变异常的小,render函数也会全部计算三次。假若 render 函数很复杂,那一个历程就白白浪费了无数计量财富。
  2. ReactJS框架比较设想DOM差别的进度,既慢又轻便出错。举个例子,倘令你想要在有个别 <ul> 列表的最上端插入生龙活虎项 <li> ,那么ReactJS框架会误以为你改改了 <ul> 的每后生可畏项 <li>,然后在尾巴部分插入了一个 <li>

那是因为 ReactJS收到的新旧七个设想DOM之间交互作用独立,ReactJS并不知道数据源爆发了怎样操作,只能依附新旧三个虚构DOM来猜测供给实行的操作。
活动的臆想算法既不许又慢,必需求前端开垦者手动提供 key 属性、shouldComponentUpdate 方法、componentDidUpdate 方法恐怕 componentWillUpdate 等艺术才干支援 ReactJS 框架猜对。

作者将要《More than React(三卡塔 尔(英语:State of Qatar)设想DOM已死?》中比较ReactJS、AngularJS和Binding.scala渲染机制,介绍轻松质量高的Binding.scala正确数据绑定机制。

Binding.scala 的主导用法

在讲课 Binding.scala 如何达成标签编辑器此前,我先介绍一些 Binding.scala 的基本功知识:

Binding.scala 中的最小复用单位是数量绑定说明式,即 @dom 方法。每个 @dom 方法是风华正茂段 HTML 模板。比方:

JavaScript

// 两个 HTML 换行符 @dom def twoBr = <br/><br/>

1
2
3
// 两个 HTML 换行符
@dom def twoBr = &lt;br/&gt;&lt;br/&gt;
 

JavaScript

// 一个 HTML 标题 @dom def myHeading(content: String) = <h1>{content}</h1>

1
2
3
// 一个 HTML 标题
@dom def myHeading(content: String) = &lt;h1&gt;{content}&lt;/h1&gt;
 

各类模板还是能运用bind语法满含其他子模板,举个例子:

JavaScript

@dom def render = { <div> { myHeading("Binding.scala的特点").bind } <p> 代码短 { twoBr.bind } 概念少 { twoBr.bind } 功能多 </p> </div> }

1
2
3
4
5
6
7
8
9
10
11
12
13
@dom def render = {
  &lt;div&gt;
    { myHeading("Binding.scala的特点").bind }
    &lt;p&gt;
      代码短
      { twoBr.bind }
      概念少
      { twoBr.bind }
      功能多
    &lt;/p&gt;
  &lt;/div&gt;
}
 

您能够参见附录:Binding.scala火速上手指南,学习上手Binding.scala开采的具体步骤。

别的,本种类第四篇文章《HTML也得以编写翻译》还将列出Binding.scala所支撑的总体HTML模板天性。

Binding.scala中的XHTML

今日有了Binding.scala ,能够在@dom艺术中,直接编写XHTML。比如:

JavaScript

@dom def introductionDiv = { <div style="font-size:0.8em"> <h3>Binding.scala的优点</h3> <ul> <li>简单</li> <li>概念少<br/>功能多</li> </ul> </div> }

1
2
3
4
5
6
7
8
9
@dom def introductionDiv = {
  <div style="font-size:0.8em">
    <h3>Binding.scala的优点</h3>
    <ul>
      <li>简单</li>
      <li>概念少<br/>功能多</li>
    </ul>
  </div>
}

如上代码会被编写翻译,直接创建真实的DOM对象,而未有伪造DOM。

Binding.scala对浏览器原生DOM的支撑很好,你能够在这里些DOM对象上调用DOM API,与 D3、jQuery等别的库人机联作也统统没不寻常。

ReactJS对XHTML语法的不尽不全。相比较之下,Binding.scala帮助完全的XHTML语法,前端技术员能够平素把规划好的HTML原型复制粘贴到代码中,整个网址就足以运作了。

难点三:ReactJS的HTML模板效率既不完善、也不健康

ReactJS支持用JSX编写HTML模板。

反对上,前端程序猿只要把静态HTML原型复制到JSX源文件中, 扩大一些变量替换代码, 就能够更动成动态页面。 理论上这种做法要比Cycle.js、Widok、ScalaTags等框架更符合复用设计员提供的HTML原型。

不幸的是,ReactJS对HTML的援助七零八落。开拓者必需手动把classfor属性替换到classNamehtmlFor,还要把内联的style体制从CSS语法改成JSON语法,代码技艺运作。 这种开辟方式下,前端程序员即便能够把HTML原型复制粘贴到代码中,但还须要大批量改建技能实际运营。 比Cycle.js、Widok、可能、ScalaTags省一再太多事。

而外,ReactJS还提供了propTypes机制校验设想DOM的合法性。 然则,那风姿罗曼蒂克体制也破绽比超多。 纵然钦定了propTypes,ReactJS也不可能在编写翻译前提前发掘错误。独有测验覆盖率超级高的品种时技能在各样组件使用任何零器件时开展校验。 就算测验覆盖率超高,propTypes反之亦然不能够检查实验出拼错的属性名,如若你把onClick写成了onclick, ReactJS就不会报错,往往产生开垦者额外开销多量岁月排查三个很简短的bug。

自家将要《More than React(四卡塔尔HTML也能够编写翻译?》中相比ReactJS和Binding.scala的HTML模板,介绍Binding.scala如何在总体帮衬XHTML语法的还要静态检查语法错误和语义错误。

难题三:ReactJS的HTML模板功用既不康健、也不健康

ReactJS支持用JSX编写HTML模板。

辩白上,前端技术员只要把静态HTML原型复制到JSX源文件中,
充实部分变量替换代码,
就会改换成动态页面。
一手包办大权独揽上这种做法要比Cycle.js、Widok、ScalaTags等框架更符合复用设计员提供的HTML原型。

噩运的是,ReactJS对HTML的支撑东鳞西爪。开采者必得手动把classfor品质替换来classNamehtmlFor,还要把内联的style体制从CSS语法改成JSON语法,代码本事运维。
这种开拓情势下,前端技术员就算能够把HTML原型复制粘贴到代码中,但还须要大量退换技艺实际运转。
比Cycle.js、Widok、恐怕、ScalaTags省不断太多事。

除开,ReactJS还提供了propTypes建制校验虚构DOM的合法性。
不过,那豆蔻梢头体制也破绽超多。
不怕内定了propTypes,ReactJS也不能够在编译前提前开掘错误。唯有测量试验覆盖率超级高的类型时技艺在每一个组件使用其余构件时开展校验。
哪怕测验覆盖率超高,propTypes反之亦然无法检查评定出拼错的属性名,若是你把onClick写成了onclick
ReactJS就不会报错,往往产生开荒者额外费用多量时光逐个审查叁个相当的粗略的bug。

自家就要《More than React(四卡塔尔国HTML也得以编写翻译?》中比较ReactJS和Binding.scala的HTML模板,介绍Binding.scala怎么着在全体帮忙XHTML语法的还要静态检查语法错误和语义错误。

Binding.scala达成的标签编辑器模板

最后,下文将突显怎么着用Binding.scala达成标签编辑器。

标签编辑器要比刚刚牵线的HTML模板复杂,因为它不不过静态模板,还含有人机联作。

JavaScript

@dom def tagPicker(tags: Vars[String]) = { val input: Input = <input type="text"/> val addHandler = { event: Event => if (input.value != "" && !tags.get.contains(input.value)) { tags.get = input.value input.value = "" } } <section> <div>{ for (tag <- tags) yield <q> { tag } <button onclick={ event: Event => tags.get -= tag }>x</button> </q> }</div> <div>{ input } <button onclick={ addHandler }>Add</button></div> </section> }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@dom def tagPicker(tags: Vars[String]) = {
  val input: Input = &lt;input type="text"/&gt;
  val addHandler = { event: Event =&gt;
    if (input.value != "" &amp;&amp; !tags.get.contains(input.value)) {
      tags.get = input.value
      input.value = ""
    }
  }
  &lt;section&gt;
    &lt;div&gt;{
      for (tag &lt;- tags) yield &lt;q&gt;
        { tag }
        &lt;button onclick={ event: Event =&gt; tags.get -= tag }&gt;x&lt;/button&gt;
      &lt;/q&gt;
    }&lt;/div&gt;
    &lt;div&gt;{ input } &lt;button onclick={ addHandler }&gt;Add&lt;/button&gt;&lt;/div&gt;
  &lt;/section&gt;
}
 

本条标签编辑器的 HTML 模板风度翩翩共用了 18 行代码就兑现好了。

标签编辑器中供给体现当前具有标签,所以那边用tags: Vars[String]封存全数的价签数据,再用for/yield循环把tags中的各个标签渲染成UI成分。

Vars 是支撑数据绑定的列表容器,每当容器中的数据发生变动,UI就能够自行退换。所以,在x按键中的onclick事件中除去tags中的数据时,页面上的价签就能活动随之消亡。相通,在Add按钮的onclick中向tags中加多数据时,页面上也会自行发出相应的竹签。

Binding.scala不但实现标签编辑器比 ReactJS 轻便,而且用起来也比 ReactJS 轻易:

JavaScript

@dom def render() = { val tags = Vars("initial-tag-1", "initial-tag-2") <div> { tagPicker(tags).bind } <h3>全体标签:</h3> <ol>{ for (tag <- tags) yield <li>{ tag }</li> }</ol> </div> }

1
2
3
4
5
6
7
8
9
@dom def render() = {
  val tags = Vars("initial-tag-1", "initial-tag-2")
  &lt;div&gt;
    { tagPicker(tags).bind }
    &lt;h3&gt;全部标签:&lt;/h3&gt;
    &lt;ol&gt;{ for (tag &lt;- tags) yield &lt;li&gt;{ tag }&lt;/li&gt; }&lt;/ol&gt;
  &lt;/div&gt;
}
 

借使用 9 行代码另写二个 HTML 模板,在模板中调用刚才完毕好的 tagPicker 就行了。

完整的 DEMO 请访问 。

在 Binding.scala 不需求像 ReactJS 这样编写 changeHandler 之类的回调函数。每当客商在 tagPicker 输入新的标签时,tags 就能转移,网页也就能够自动随之变动。

相比 ReactJS 和 Binding.scala 的代码,能够开采以下分别:

  • Binding.scala 的开垦者能够用临近 tagPicker 这样的 @dom 方法表示 HTML 模板,而无需组件概念。
  • Binding.scala 的开辟者能够在点子之间传递 tags 那样的参数,而不供给 props 概念。
  • Binding.scala 的开荒者能够在点子钦点义局地变量表示处境,而没有须要 state 概念。

看来 Binding.scala 要比 ReactJS 精练不菲。

若是您用过 ASP 、 PHP 、 JSP 之类的服务端网页模板语言, 你会开掘和 Binding.scala 的 HTML 模板很像。

行使 Binding.scala 一点也无需函数式编制程序知识,只要把设计工具中生成的 HTML 原型复制到代码中,然后把会变的部分用花括号替代、把重复的有个别用 for / yield 代替,网页就办好了。

Binding.scala中XHTML的类型

@dom主意中XHTML对象的连串是Node的派生类。

比如,<div></div> 的门类就是HTMLDivElement,而 <button></button> 的品种就是 HTMLButtonElement。

此外, @dom 评释会校订总体艺术的重临值,包装成三个Binding。

JavaScript

@dom def typedButton: Binding[HTMLButtonElement] = { <button>按钮</button> }

1
2
3
@dom def typedButton: Binding[HTMLButtonElement] = {
  <button>按钮</button>
}

注意typedButton是个原生的HTMLButtonElement,所以能够直接对它调用 DOM API。举例:

JavaScript

@dom val autoPrintln: Binding[Unit] = { println(typedButton.bind.innerHTML) // 在调节台南打字与印刷按键内部的 HTML } autoPrintln.watch()

1
2
3
4
@dom val autoPrintln: Binding[Unit] = {
  println(typedButton.bind.innerHTML) // 在控制台中打印按钮内部的 HTML
}
autoPrintln.watch()

这段代码中,typedButton.bind.innerHTML 调用了 DOM API HTMLButtonElement.innerHTML。通过autoPrintln.watch(),每当按键发生更新,autoPrintln中的代码就能够进行三遍。

主题材料四:ReactJS与服务器通信时索要复杂的异步编制程序

ReactJS从服务器加载数据时的构造能够视作MVVM(Model–View–ViewModel)格局。 前端程序员必要编写制定一个数据库访谈层作为Model,把ReactJS的state当做ViewModel,而render作为View。 Model担负访谈数据库并把数据设置到state(即View Model)上,可以用Promise和fetch API实现。 然后,render,即View,肩负把View Model渲染到页面上。

在此意气风发体流程中,前端技士须求编写制定多量闭包组成的异步流程, 设置、访谈状态的代码五零四散, 一相当大心就能够bug丛生,纵然小心翼翼的拍卖各类异步事件,也会招致程序变得复杂,既难调试,又难保险。

本人将要《More than React(五卡塔 尔(阿拉伯语:قطر‎为何别用异步编制程序?》中相比ReactJS和Binding.scala的数据同步模型,介绍Binding.scala怎样自动同步服务器数据,防止手动异步编程。

难点四:ReactJS与服务器通讯时索要复杂的异步编制程序

ReactJS从服务器加载数据时的结构可以用作MVVM(Model–View–ViewModel)方式。
前面一个程序员必要编写制定多少个数据库访问层作为Model,把ReactJS的state当做ViewModel,而render当做View。
Model担当访谈数据库并把多少设置到state(即View Model)上,可以用Promise和fetch API实现。
然后,render,即View,肩负把View Model渲染到页面上。

在这里朝气蓬勃体流程中,前端程序员供给编写制定大批量闭包组成的异步流程,
安装、访谈状态的代码五零四散,
轻率就能够bug丛生,纵然小心审慎的拍卖各个异步事件,也会变成程序变得复杂,既难调节和测量试验,又难保证。

自作者将要《More than React(五卡塔 尔(阿拉伯语:قطر‎为何别用异步编程?》中比较ReactJS和Binding.scala的数量同步模型,介绍Binding.scala怎么样自动同步服务器数据,幸免手动异步编制程序。

结论

本文相比较了不相同本事栈中完成和使用可复用的竹签编辑器的难度。

原生 HTML ReactJS Binding.scala
实现标签编辑器需要代码行数 45行 51行 17行
实现标签编辑器的难点 在代码中动态更新HTML页面太繁琐 实现组件的语法很笨重
使用标签编辑器并显示标签列表需要代码行数 难以复用 21行 8行
阻碍复用的难点 静态HTML元素难以模块化 交互组件之间层层传递回调函数过于复杂

Binding.scala 不注明“组件”之类的玩笑,而以更轻松的“方法”为最小复用单位,让编程体验越来越百发百中,获得了越来越好的代码复用性。

本体系下风华正茂篇小说将相比 ReactJS 的设想 DOM 机制和 Binding.scala 的纯正数据绑定机制,报料 ReactJS 和 Binding.scala 相通用法背后掩藏的例外算法。

其他HTML节点

Binding.scala支持HTML注释:

JavaScript

@dom def comment = { <!-- 你看不见作者 --> }

1
2
3
@dom def comment = {
  <!-- 你看不见我 -->
}

Binding.scala也支持CDATA块:

JavaScript

@dom def inlineStyle = { <section> <style><![CDATA[ .highlight { background-color:gold } ]]></style> <p class="highlight">Binding.scala真好用!</p> </section> }

1
2
3
4
5
6
7
8
9
10
@dom def inlineStyle = {
  <section>
    <style><![CDATA[
      .highlight {
        background-color:gold
      }
    ]]></style>
    <p class="highlight">Binding.scala真好用!</p>
  </section>
}

结论

固然Binding.scala初看上去很像ReactJS, 但隐蔽在Binding.scala背后的体制更简便、更通用,与ReactJS和Widok天差地别。

进而,通过简化概念,Binding.scala灵活性越来越强,能用通用的措施解除ReactJS消除不了的繁琐难点。

比方说,除了上述三个地点以外,ReactJS的景观处理也是没有办法子难点,假使引进Redux或许react-router那样的第三方库来处理状态,会促成结构变复杂,分层变多,代码绕来绕去。而Binding.scala能够用和页面渲染同样的多寡绑定机制描述复杂的情形,没有必要别的第三方库,就能够提供服务器通讯、状态管理和网站分发的法力。

以下表格中列出了上述Binding.scala和ReactJS的功力差别:

Binding.scala

ReactJS

复用性

小小复用单位

方法

组件

复用难度

无论人机联作内容还是静态内容都轻易复用

轻巧复用静态内容组件,但有口难言复用人机联作组件

页面渲染算法

算法

确切的数目绑定

虚拟 DOM

性能

正确性

自动保证科学

内需开拓者手动设置 key 属性,否则复杂的页面会混杂。

HTML 模板

语法

Scala XML 字面量

JSX

是否帮忙 HTML 或 XHTML 语法

全部协理 XHTML

残破扶持。平日的 XHTML 不可能编译。开垦者必须手动把 classfor 属性替换到 classNamehtmlFor,还要把内联的 style 样式从 CSS 语法改成 JSON 语法。

何以校验模板语法

机关编写翻译时校验

运营时经过 propTypes 校验但不可能检查测验大约的拼写错误。

服务器通信

机制

自行远程数据绑定

MVVM 异步编制程序

兑现难度

简单

复杂

其他

怎么分担网站大概锚点链接

支撑把网站当成普通的绑定变量来用,无需第三方库。

不扶植,要求第三方库 react-router

职能完善性

完全的前端开荒应用方案

本身只包涵视图部分机能。供给相当驾驭 react-router 、 Redux 品级三方库本事促成豆蔻年华体化的前端项目。

学习曲线

API 简单,对没用过 Scala 的人来讲也很好懂

上心灵。但职能太弱招致早先时期学习第三方库时曲线陡峭。

Binding.scala

ReactJS

四个多月前,小编在Scala.js的论坛宣布Binding.scala时,此时Scala.js社区最风靡的响应式前端编制程序框架是Widok。TimNieradzik是Widok的笔者。他在看见自个儿宣布的框架后,表彰那一个框架是Scala.js社区最有前途的 HTML 5渲染框架。

她是对的,七个月后,现在Binding.scala已经济体改为Scala.js社区最流行的响应式前端编制程序框架。

Awesome Scala网站相比较了Scala的响应式前端编制程序框架,Binding.scala的生意盎然程度和流行度都比Udash、Widok等其他框架要高。

图片 3

自我在如今的多少个品种中,也日益吐弃JavaScript和ReactJS,改用Scala.js和Binding.scala搭建新时代的前端本领栈。

结论

即使Binding.scala初看上去很像ReactJS,
但蒙蔽在Binding.scala背后的体制更简单、更通用,与ReactJS和Widok判若霄壤。

进而,通过简化概念,Binding.scala灵活性越来越强,能用通用的措施清除ReactJS解决不了的头眼昏花难题。

例如,除了上述三个地方以外,ReactJS的景况管理也是吃力难点,即使引进Redux或许react-router那样的第三方库来拍卖状态,会以致构造变复杂,分层变多,代码绕来绕去。而Binding.scala能够用和页面渲染同样的数据绑定机制描述复杂的情形,没有必要其它第三方库,就会提供服务器通讯、状态管理和网址分发的效率。

以下表格中列出了上述Binding.scala和ReactJS的法力差别:

3-sheet.png

多少个多月前,小编在Scala.js的论坛发表Binding.scala时,这个时候Scala.js社区最盛行的响应式前端编制程序框架是Widok。TimNieradzik是Widok的撰稿者。他在见到自家公布的框架后,赞誉这一个框架是Scala.js社区最有前景的 HTML 5渲染框架。

她是对的,五个月后,以往Binding.scala已经变为Scala.js社区最风靡的响应式前端编程框架。

Awesome Scala网站对待了Scala的响应式前端编制程序框架,Binding.scala的活泼程度和流行度都比Udash、Widok等其余框架要高。

自己在近日的多少个种类中,也稳步舍弃JavaScript和ReactJS,改用Scala.js和Binding.scala搭建新时期的前端技巧栈。

连锁链接

  • Binding.scala 项目主页
  • Binding.scala • TodoMVC 项目主页
  • Binding.scala • TodoMVC DEMO
  • Binding.scala • TodoMVC 以外的任何 DEMO
  • JavaScript 到 Scala.js 移植指南
  • Scala.js 项目主页
  • Scala API 参照他事他说加以侦查文书档案
  • Scala.js API 参谋文书档案
  • Scala.js DOM API 参照他事他说加以考察文书档案
  • Binding.scala快速上手指南
  • Binding.scala API参谋文书档案
  • Binding.scala 的 Gitter 聊天室

    1 赞 1 收藏 评论

内嵌Scala代码

除去能够把XHTML内嵌在Scala代码中的 @dom 方法中,Binding.scala 还帮衬用 { ... } 语法把 Scala 代码内嵌到XHTML中。譬如:

JavaScript

@dom def randomParagraph = { <p>生成四个大肆数: { math.random.toString }</p> }

1
2
3
@dom def randomParagraph = {
  <p>生成一个随机数: { math.random.toString }</p>
}

XHTML中内嵌的Scala代码能够用 .bind 绑定变量或然调用别的 @dom 方法,比如:

JavaScript

val now = Var(new Date) window.setInterval(1000) { now := new Date } @dom def render = { <div> 今后时刻:{ now.bind.toString } { introductionDiv.bind } { inlineStyle.bind } { typedButton.bind } { comment.bind } { randomParagraph.bind } </div> }

1
2
3
4
5
6
7
8
9
10
11
12
13
val now = Var(new Date)
window.setInterval(1000) { now := new Date }
 
@dom def render = {
  <div>
    现在时间:{ now.bind.toString }
    { introductionDiv.bind }
    { inlineStyle.bind }
    { typedButton.bind }
    { comment.bind }
    { randomParagraph.bind }
  </div>
}

上述代码渲染出的网页中,时间会动态退换。

连锁链接

  • Binding.scala 项目主页
  • Binding.scala • TodoMVC 项目主页
  • Binding.scala • TodoMVC DEMO
  • Binding.scala • TodoMVC 以外的别样 DEMO
  • JavaScript 到 Scala.js 移植指南
  • Scala.js 项目主页
  • Scala API 仿效文书档案
  • Scala.js API 参谋文档
  • Scala.js DOM API 参考文书档案
  • Binding.scala神速上手指南
  • Binding.scala API参谋文书档案
  • Binding.scala 的 Gitter 聊天室

    1 赞 5 收藏 15 评论

连锁链接

  • Binding.scala 项目主页
  • Binding.scala • TodoMVC 项目主页
  • Binding.scala • TodoMVC DEMO
  • Binding.scala • TodoMVC 以外的别样 DEMO
  • JavaScript 到 Scala.js 移植指南
  • Scala.js 项目主页
  • Scala API 参谋文书档案
  • Scala.js API 参考文书档案
  • Scala.js DOM API 参谋文书档案
  • Binding.scala飞速上手指南
  • Binding.scala API参照他事他说加以考察文书档案
  • Binding.scala 的 Gitter 聊天室

关于小编:ThoughtWorks

图片 4

ThoughtWorks是一家中外IT咨询集团,追求卓越软件品质,致力于科技(science and technology)驱动商业变革。专长营造定制化软件出品,支持客商高效将概念转变为价值。同临时间为顾客提供顾客体验设计、技巧战术咨询、组织转型等咨询服务。 个人主页 · 笔者的稿子 · 84 ·   

图片 5

强类型的 XHTML

Binding.scala中的XHTML 都扶植静态类型检查。举个例子:

JavaScript

@dom def typo = { val myDiv = <div typoProperty="xx">content</div> myDiv.typoMethod() myDiv }

1
2
3
4
5
@dom def typo = {
  val myDiv = <div typoProperty="xx">content</div>
  myDiv.typoMethod()
  myDiv
}

出于以上代码有拼写错误,编写翻译器就能够报错:

JavaScript

typo.scala:23: value typoProperty is not a member of org.scalajs.dom.html.Div val myDiv = <div typoProperty="xx">content</div> ^ typo.scala:24: value typoMethod is not a member of org.scalajs.dom.html.Div myDiv.typoMethod() ^

1
2
3
4
5
6
typo.scala:23: value typoProperty is not a member of org.scalajs.dom.html.Div
        val myDiv = <div typoProperty="xx">content</div>
                     ^
typo.scala:24: value typoMethod is not a member of org.scalajs.dom.html.Div
        myDiv.typoMethod()
              ^

有关小编:ThoughtWorks

图片 6

ThoughtWorks是一家中外IT咨询公司,追求卓绝软件品质,致力于科技(science and technology)驱动商业变革。长于创设定制化软件出品,扶植顾客高效将概念转变为价值。同期为顾客提供客户体验设计、才能战术咨询、协会转型等咨询服务。 个人主页 · 笔者的篇章 · 84 ·   

图片 7

内联CSS属性

style 属性设置内联样式时,style 的值是个字符串。举例:

JavaScript

@dom def invalidInlineStyle = { <div style="color: blue; typoStyleName: typoStyleValue"></div> }

1
2
3
@dom def invalidInlineStyle = {
  <div style="color: blue; typoStyleName: typoStyleValue"></div>
}

以上代码中装置的 typoStyleName 样式名写错了,但编写翻译器并未报错。

要想让编写翻译器能检查内联样式,可以用 style: 前缀而不用 style 属性。比如:

JavaScript

@dom def invalidInlineStyle = { <div style:color="blue" style:typoStyleName="typoStyleValue"></div> }

1
2
3
@dom def invalidInlineStyle = {
  <div style:color="blue" style:typoStyleName="typoStyleValue"></div>
}

那么编写翻译器就能报错:

JavaScript

typo.scala:28: value typoStyleName is not a member of org.scalajs.dom.raw.CSSStyleDeclaration <div style:color="blue" style:typoStyleName="typoStyleValue"></div> ^

1
2
3
typo.scala:28: value typoStyleName is not a member of org.scalajs.dom.raw.CSSStyleDeclaration
        <div style:color="blue" style:typoStyleName="typoStyleValue"></div>
         ^

这样一来,能够在编写制定代码时就知晓属性有未有写对。不像原生JavaScript / HTML / CSS这样,碰到bug也查不出去。

自定义属性

若果你要求绕开对品质的等级次序检查,以便为HTML成分增添定制数据,你可以属性加上 data: 前缀,比如:

JavaScript

@dom def myCustomDiv = { <div data:customAttributeName="attributeValue"></div> }

1
2
3
@dom def myCustomDiv = {
  <div data:customAttributeName="attributeValue"></div>
}

那样一来Scala编写翻译器就不会报错了。

结论

正文的后生可畏体化DEMO请访问 ScalaFiddle。

从这个示例能够观察,Binding.scala 一方面辅助完全的XHTML ,能够从高保真HTML 原型无缝移植到动态网页中,开荒进度极为流畅。其他方面,Binding.scala 能够在编写翻译时静态检查XHTML中冒出语法错误和语义错误,进而防止bug 。

以下表格相比了ReactJS和Binding.scala对HTML语法的协助程度:

ReactJS Binding.scala
是否支持HTML语法? 残缺支持
是否支持标准的style属性? 不支持,必须改用 JSON 语法
是否支持标准的class属性? 不支持,必须改用className
是否支持标准的for属性? 不支持,必须改用htmlFor
是否支持HTML注释? 不支持
是否兼容原生DOM操作? 不兼容
是否兼容jQuery? 不兼容
能否在编译时检查出错误? 不能

小编就要下生龙活虎篇小说中介绍 Binding.scala 怎么样得以达成服务器发送央求并在页面展现结果的流水生产线。

连锁链接

  • Binding.scala 项目主页
  • Binding.scala • TodoMVC 项目主页
  • Binding.scala • TodoMVC DEMO
  • Binding.scala • TodoMVC 以外的任何 DEMO
  • JavaScript 到 Scala.js 移植指南
  • Scala.js 项目主页
  • Scala API 仿照效法文书档案
  • Scala.js API 参谋文书档案
  • Scala.js DOM API 仿效文档
  • Binding.scala赶快上手指南
  • Binding.scala API参谋文档
  • Binding.scala 的 Gitter 聊天室

    1 赞 1 收藏 1 评论

有关俺:ThoughtWorks

图片 8

ThoughtWorks是一家中外IT咨询公司,追求优质软件品质,致力于科学和技术驱动商业变革。专长创设定制化软件出品,援助客商高效将定义转变为价值。同一时间为客商提供客商体验设计、本领战术咨询、组织转型等咨询服务。 个人主页 · 小编的稿子 · 84 ·   

图片 9

本文由pc28.am发布于前端技术,转载请注明出处:HTML也可以静态编译,损害了复用性

上一篇:前端框架这么多 下一篇:没有了
猜你喜欢
热门排行
精彩图文
  • HTML也可以静态编译,损害了复用性
    HTML也可以静态编译,损害了复用性
    React.Component 损害了复用性? 2016/09/07 · 底蕴技能 ·binding.scala,data-binding,React,scala.js 本文笔者: 伯乐在线 -ThoughtWorks。未经笔者许可,防止转发! 接待插足
  • 品质的法门
    品质的法门
    9 种改革 AngularJS 品质的艺术 2017/07/20 · JavaScript· AngularJS 初藳出处: JustinSpencer   译文出处:oschina    AngularJS 是当下利用非常遍布的 web app应用框架,随
  • 高质量滚动,实例解析防抖动和节流阀
    高质量滚动,实例解析防抖动和节流阀
    实例解析防抖动和节流阀 2016/04/26 · JavaScript· DOM 本文由 伯乐在线 -涂鸦码龙翻译。未经许可,幸免转发! 立陶宛共和国(Republic of Lithuania卡塔尔语出处:
  • 安插最棒执行,营造打包优化_javascript技术_脚本
    安插最棒执行,营造打包优化_javascript技术_脚本
    Webpack 4 配置最佳实践 2018/06/22 · JavaScript· webpack 原文出处:Zindex    Webpack 4 发布已经有一段时间了。Webpack 的版本号已经来到了4.12.x。但因为 Webpack官方还
  • 前端安全
    前端安全
    Web 安全之 XSS 2018/05/25 · JavaScript· 1 评论 ·XSS 原文出处:今日头条技术博客    1.CSRF 2.XSS 基本概念 攻击原理 防御措施 什么是XSS 跨站脚本攻击(Cross Site