前端神器avalonJS入门(一)

avalonJS是司徒正美开发和维护的前端mvvm框架,可以轻松实现数据的隔离和双向绑定,相比angularJS等前端框架它有如下优势:

1.压缩后仅有60多kb,而angular的min版是100多kb;

2.兼容IE6+,符合天朝市场需求;

3.效率更高,跑起来比angular和knockout都要更快,在移动端上该优势会更大(avalon有移动端专版的avalon.modern.js)。关于其性能更详细的介绍可以看这里;

4.涵盖了angular的大部分功能,且实现方式更为便捷、上手更容易;

5.有配套的UI库(当然这个按需选择即可),由司徒正美及其“去哪儿”团队维护,有相关的中文文档(下方会提到),除了在github提交issue,你也可以加入正美的Q群79641290 来交流问题或提交bug。

(这位兄台,谷歌送温暖,开门查水表)

然而avalon也有自己的劣势——知名度较低。不过毕竟国产的东西没经BAT推广,要像seaJS那样驰名中外倒是不容易。

相关中文文档

正美其实私下写了不少avalon的官方api和教程,大家可以访问如下地址:

GitHub(下载最新的avalon以及实例(examples文件夹里),通过实例来掌握某些功能的实现是很好的学习途径)

Avalon简单介绍

Avalon快速入门(比较快捷的入门课程,只用了几篇文章来介绍了最常用的一些功能)

API文章(正美的博文,篇幅较大,涵盖知识点很多,可以当作API来查阅,只是正美的博客排版真的。。。看起来略吃力),也可以在这里查看更规范的API。

Avalon乱炖(强烈推荐,用了20多篇文章较详细地、渐进地介绍avalon,必读的就是啦)

Avalon入门视频(推荐)

本系列初衷

虽然正美已经细心编写了不少中文文档,不过有的文章技术门槛有点高,不太适合初学者,另外作为avalon的用户,以用户的角度来较详细地介绍avalon或许会更合适些。

本系列相比正美的教程,会更侧重于“怎么用”,而非其机制或原理的介绍。

另外也希望本系列能为推广avalon出一份绵薄之力,希望能让更多的前端爱好者开始接触avalon,并喜欢上这个前端利器。

本系列技术需求

本系列除了avalonJS之外,还会搭配requireJS做辅助,特别是后面我们会使用avalon的路由系统,来做一个单页面站点(放到移动端就是SPA了),需要requireJS及其插件来按需加载脚本和样式文件,故建议查阅本系列的朋友要多多少少会一点requireJS的知识。

个人还是觉得avalon搭配requireJS的话,在前端可谓hold住全场了(咱忽略node及其框架...)~

开始

我们可以在这里获取最新版本的avalonJS,然后将其引入页面中(本章先不考虑搭配requireJS,仅仅先玩一玩、介绍下):

DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>初玩阿瓦隆title>
    <script type="text/javascript" src="avalon.js">script>
head>
<body>
<div>div>
body>
html>

接着,类似于ng的“ng-controller”,avalon的控制域属性名叫做“ms-controller”,你可以把它当作一个监听器,把它绑定到一个容器后,avalon就能扫描和监听这个容器内的所有(绑定了avalon方法或带有插值表达式的)元素了。

我们来给div加上这个监听器,并在里面写一个avalon插值表达式{{XXX}}:

<div ms-controller="wrap">{{a}}div>

你现在运行它的话,还没有任何效果,因为我们还没有写脚本来让avalon工作起来。我们可以来这么一段简单的脚本:

<body>
<div ms-controller="wrap">{{a}}div>
<script type="text/javascript">
    var abc = avalon.define({  //abc是随便起的一个名字,用作该Model的载体
        $id: "wrap",   //告诉avalon这个Model是作用于哪个ms-controller的
        a: "你好啊"   //定义一个avalon对象属性“a”,其值是“你好啊”
    });
    avalon.scan(); //这句话可以不加,因为avalon有自己的DOMReady模块,会自动扫描全文。
script>
body>

在avalon中,我们用 avalon.define({ ... }) 的形式来定义一个Model实例(其参数可以看做一个avalon数据对象),其中的 $id 是内置属性,对应所要扫描和监控的控制域名。

我们还在内部定义了一个属性"a",故在对应的控制域(如这段代码对应的域是绑定ms-controller="wrap"的div标签)里,我们使用avalon插值表达式{{a}}的话,可以自动绑定其值“你好啊”。

注:最后一句 avalon.scan(); 可以不加上,不过后续我们会使用requireJS来配合使用avalon,届时会建议删掉avalon的DOMReady模块,故先养成加上scan的习惯。

上述代码运行效果如下:

前端神器avalonJS入门(一)_第1张图片

当然,avalon有着更类似ng的写法:

avalon.define("wrap", function(vm) {
  ......
})

但个人觉得没必要,还是下方的写法来的简单(本系列后续的实例也将遵从该写法):

var vm = avalon.define({
    $id:wrap,
    ......
})

下面这段代码可以帮你更好了解avalon的控制域:

<body>
<div ms-controller="wrap">{{a}}div>
<div ms-controller="wrap2">
    {{a}}
    <span>{{b}}span>
div>
<script type="text/javascript">
    var abc = avalon.define({
        $id: "wrap",
        a: "你好啊"
    });
    var def = avalon.define({
        $id: "wrap2",
        a: "大家好",
        b: "哈哈哈"
    });
    avalon.scan(); 
script>
body>

执行效果如下:

前端神器avalonJS入门(一)_第2张图片

两个作用域(ms-controller)之间可以互相访问彼此的数据,还记得我们给avalon.define的前面定义了一个载体么(var XX = avalon.define),利用它就能轻松获取:

<body>
<div ms-controller="wrap">{{a}}div>
<div ms-controller="wrap2">
    {{a}}
    <span>{{b}}span>
div>
<script type="text/javascript">
    var abc = avalon.define({
        $id: "wrap",
        a: "你好啊"
    });
    var def = avalon.define({
        $id: "wrap2",
        a: "大家好",
        b: abc.a   //获取第一个Model里的属性值
    });
    avalon.scan();
script>
body>

执行效果:

前端神器avalonJS入门(一)_第3张图片

数据和视图同步

上方我们实现了非常简单的数据绑定,将一个avalon对象属性a绑定到DOM元素上。不过avalon更有趣和实用的地方是它实现了数据与视图的同步,说的简单点,我们用脚本修改了a的值,那么DOM上绑定的数据也会跟着改变(当然反过来也是一样的):

<body>
<div ms-controller="wrap">
    <span>{{a}}span>
    <input ms-duplex="a" />
div>
<script type="text/javascript">
    var abc = avalon.define({
        $id: "wrap",
        a: "你好啊"
    });
    avalon.scan();
script>
body>

注意我们这里增加了一个 ms-duplex="a" /> ,其中的 ms-duplex 是avalon的双工绑定属性,它除了负责将VM中对应的值(如本例是a)放到表单元素的value中,还对元素偷偷绑定一些事件,用于监听用户的输入从而自动刷新VM。

执行如下:

前端神器avalonJS入门(一)_第4张图片

实例

利用avalon数据-视图同步的特性,我们可以更便捷地、更少代码地实现某些功能。举个例子,我们来实现一个选项卡的功能:

前端神器avalonJS入门(一)_第5张图片

如上图的选项卡你会如何实现呢?可能你会写两个ul来对应下方两个选项卡列表,每个ul里都写上4个li(或者让后端人员通过后端框架来写loop,从而动态生成li),然后你再把第二个ul隐藏了,接着写个方法,让鼠标移到第二个选项卡标题时,第一个ul隐藏,第二个ul显示,对吧。

还有右上角的 “更多XX” 的连接,也可以通过隐藏-显示的方式来实现

你的DOM代码可能是这样的:

<div>
  <span id="gg">公告span><span id="bd">媒体报道span>
  <a id="more_gg" href="#!/gg">更多公告a><a id="more_bd" href="#!/bd">更多报道a>
  <ul id="gg_list">
      <li><a href="#!/gg/1" title="公告文章标题1">公告文章标题1a>li>
      <li><a href="#!/gg/2" title="公告文章标题2">公告文章标题2a>li>
      <li><a href="#!/gg/3" title="公告文章标题3">公告文章标题3a>li>
      <li><a href="#!/gg/4" title="公告文章标题4">公告文章标题4a>li>
  ul>
  <ul id="bd_list">
      <li><a href="#!/bd/1" title="媒体报道文章标题1">媒体报道文章标题1a>li>
      <li><a href="#!/bd/2" title="媒体报道文章标题2">媒体报道文章标题2a>li>
      <li><a href="#!/bd/3" title="媒体报道文章标题3">媒体报道文章标题3a>li>
      <li><a href="#!/bd/4" title="媒体报道文章标题4">媒体报道文章标题4a>li>
  ul>
div>

但使用avalon的话,一切都更简单:

<div ms-controller="list">
    <span ms-mouseover="changeUl(gg)">公告span>
    <span ms-mouseover="changeUL(bd)">媒体报道span>
    <a ms-href="'#!/'+ more_name">{{more_text}}a>
    <ul>
        <li ms-repeat="infoList">
            <a ms-href="'#!/'+ more_name + '/' + el.id" ms-title="el.title">{{el.title}}a>
        li>
    ul>
div>

首先它只有一个“更多XX”的标签,而且只有一个

转载于:https://www.cnblogs.com/vajoy/p/4063824.html

你可能感兴趣的:(前端神器avalonJS入门(一))