前端神器avalonJS入门(一)

2023-11-15

http://www.360doc.com/content/14/1031/20/21412_421521791.shtml

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

1.压缩后仅有60多kb,而angular的min版是2MB左右(无视其gzip版);

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,并喜欢上这个前端利器。

本系列技术需求

本系列除了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扫描文档,从而执行起来
</script>
</body>

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

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

上述代码运行效果如下:

当然,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>

执行效果如下:

两个作用域(ms-controller)之间可以互相访问彼此的数据,还记得我们给avalon.define的前面定义了一个载体么(varXX= 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>

执行效果:

数据和视图同步

上方我们实现了非常简单的数据绑定,将一个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>

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

执行如下:

实例

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

如上图的选项卡你会如何实现呢?可能你会写两个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">公告文章标题1</a></li>
    <li><a href="#!/gg/2" title="公告文章标题2">公告文章标题2</a></li>
    <li><a href="#!/gg/3" title="公告文章标题3">公告文章标题3</a></li>
    <li><a href="#!/gg/4" title="公告文章标题4">公告文章标题4</a></li>
  </ul>
  <ul id="bd_list">
    <li><a href="#!/bd/1" title="媒体报道文章标题1">媒体报道文章标题1</a></li>
    <li><a href="#!/bd/2" title="媒体报道文章标题2">媒体报道文章标题2</a></li>
    <li><a href="#!/bd/3" title="媒体报道文章标题3">媒体报道文章标题3</a></li>
    <li><a href="#!/bd/4" title="媒体报道文章标题4">媒体报道文章标题4</a></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”的<a>标签,而且只有一个<ul>,而且不存在任何后端标签的介入就能实现数据循环绑定。

它的优势在数据越多的时候会越明显(例如每个ul要显示100条li)。

我们来看看avalon的脚本应当怎么写:

<body>
<script type="text/javascript">
  var gg=[{"id":"1","title":"公告文章标题1"},{"id":"2","title":"公告文章标题2"},{"id":"3","title":"公告文章标题3"},{"id":"4","title":"公告文章标题4"}];
  var bd=[{"id":"1","title":"媒体报道文章标题1"},{"id":"2","title":"媒体报道文章标题2"},{"id":"3","title":"媒体报道文章标题3"},{"id":"4","title":"媒体报道文章标题4"}];
</script>
<div ms-controller="list">
  <span ms-mouseover="changeUl(1)">公告</span>
  <span ms-mouseover="changeUl(0)">媒体报道</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>
<script type="text/javascript">
  var vm = avalon.define({
    $id: "list",
    more_name: "gg",
    more_text: "更多公告",
    gg:gg,
    bd:bd,
    infoList:gg,
    changeUl:function(flag){
      if(flag){  //鼠标移过“公告”选项卡头部
        vm.more_name = "gg";
        vm.more_text = "更多公告";
        vm.infoList = vm.gg;
      }else{  //鼠标移过“媒体报道”选项卡头部
        vm.more_name = "bd";
        vm.more_text = "更多报道";
        vm.infoList = vm.bd;
      }
    }
  });
  avalon.scan();
</script>
</body>

执行效果:

我们来逐步分析下上方的代码。首先看第一段脚本:

<script type="text/javascript">
    var gg=[{"id":"1","title":"公告文章标题1"},{"id":"2","title":"公告文章标题2"},{"id":"3","title":"公告文章标题3"},{"id":"4","title":"公告文章标题4"}];
    var bd=[{"id":"1","title":"媒体报道文章标题1"},{"id":"2","title":"媒体报道文章标题2"},{"id":"3","title":"媒体报道文章标题3"},{"id":"4","title":"媒体报道文章标题4"}];
</script>

这里的 gg 表示“公告”的列表JSON数据,bd 则是“媒体报道”的列表JSON数据,你可以让后端的朋友直接在此处提供JSON数据过来。我们后续会利用avalon把这些数据绑定到页面视图上。

我们再看DOM结构:

<div ms-controller="list">
  <span ms-mouseover="changeUl(1)">公告</span>
  <span ms-mouseover="changeUl(0)">媒体报道</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>

<span>中的 ms-mouseover 是avalon的“onmouseover”方法,其值 changeUl(X) 是我们在最后的avalon脚本中定义的一个事件方法,然后比如当鼠标移到“媒体报道”的span上,会触发绑定是 changeUl(0) 事件。

我们再看看 <ams-href="'#!/'+ more_name">{{more_text}}</a>  这里的 ms-href 自然也是avalon中的“href”属性,可以植入avalon对象属性(如这里的more_name),也可以加上字符串(如这里的'#!/'),但要用引号括起来,不然会被当作avalon对象属性处理。

接着是最重要的部分:

<li ms-repeat="infoList">
      <a ms-href="'#!/'+ more_name + '/' + el.id" ms-title="el.title">{{el.title}}</a>
</li>

我们使用了 ms-repeat="XX" 属性来绑定要重复显示的哈希数据,同时会生成一个代理VM对象,该代理对象拥有el,$index, $first, $last, $remove 等属性(点这里查看详细),其中我们用到的 el 表示指向当前的数据元素,从而可以通过 el.id ,el.title 来获取infoList数组对象的具体元素。

最后咱再看看avalon脚本:

<script type="text/javascript">
  var vm = avalon.define({
    $id: "list",
    more_name: "gg",
    more_text: "更多公告",
    gg:gg,   //获取公告JSON数据
    bd:bd,   //获取媒体报道JSON数据
    infoList:gg,  //infoList缺省值为公告JSON数据
    changeUl:function(flag){
      if(flag){  //鼠标移过“公告”选项卡头部
        vm.more_name = "gg";
        vm.more_text = "更多公告";
        vm.infoList = vm.gg;   //infoList变为公告JSON数据
      }else{  //鼠标移过“媒体报道”选项卡头部
        vm.more_name = "bd";
        vm.more_text = "更多报道";
        vm.infoList = vm.bd;   //infoList变为媒体报道JSON数据
      }
    }
  });
  avalon.scan();
</script>

这里要注意的是我们用了

gg:gg,   //获取公告JSON数据
        bd:bd,   //获取媒体报道JSON数据

来获取和存储“公告/媒体报道”的JSON数据到avalon对象的属性中(左侧的gg和bd是avalon对象属性,右侧的gg和bd是全局变量),这样做的原因是后续的回调事件changeUl(flag)要通过参数来判断和修改vm.infoList的值,而其值应同为avalon对象属性。如果把代码改为这样会出错(刚用avalon的朋友可能就会这样写):

<script type="text/javascript">
  var vm = avalon.define({
    $id: "list",
    more_name: "gg",
    more_text: "更多公告",
    infoList:gg,  //infoList缺省值为公告JSON数据
    changeUl:function(flag){
      if(flag){  //鼠标移过“公告”选项卡头部
        vm.more_name = "gg";
        vm.more_text = "更多公告";
        vm.infoList = gg;  
      }else{  //鼠标移过“媒体报道”选项卡头部
        vm.more_name = "bd";
        vm.more_text = "更多报道";
        vm.infoList = bd; 
      }
    }
  });
  avalon.scan();
</script>

执行效果如下:

是的,鼠标第一次移上去的时候是无误的,但再移到其它选项卡的时候就不按常理出牌了,这是为什么?

我个人认为,在我们第一次获取全局变量之后,avalon就会把该变量变为一个avalon对象,导致该变量的值就这么被改变了,你可以这样来调试:

var vm = avalon.define({
    $id: "list",
    more_name: "gg",
    more_text: "更多公告",
    gg:gg, 
    bd:bd, 
    infoList:gg, 
    changeUl:function(flag){
      console.table(gg); //console出“公告”变量的数据信息
      if(flag){ 
        vm.more_name = "gg";
        vm.more_text = "更多公告";
        vm.infoList = vm.gg;  
      }else{  
        vm.more_name = "bd";
        vm.more_text = "更多报道";
        vm.infoList = vm.bd; 
      }
    }
  });
  avalon.scan();

结果(第一次回调事件的gg是正常的,但第二次开始就改变了):

因此我们要记得,若存在外部引入的数据,应用一个avalon对象属性保存起来。

第一篇入门文章就到这里,下一篇我们开始以配合requireJS的形式来使用avalon,共勉~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

前端神器avalonJS入门(一) 的相关文章

  • Nginx 第三方健康检测模块的使用

    ngx http upstream check module 模块 模块开源地址 https github com yaoweibin nginx upstream check module 官网介绍 http tengine taobao
  • linux 网络

    网络基础 协议的概念 什么是协议 从应用的角度出发 协议可理解为 规则 是数据传输和数据的解释的规则 假设 A B双方欲传输文件 规定 第一次 传输文件名 接收方接收到文件名 应答OK给传输方 第二次 发送文件的尺寸 接收方接收到该数据再次
  • tf好朋友之matplotlib的使用——subplot分格显示

    tf好朋友之matplotlib的使用 subplot分格显示 分格显示的方法 利用plt subplot2grid进行分格显示 利用gridspec GridSpec进行分格显示 应用示例 在学习matlab的时候 图像是可以分格显示的
  • 1032. 挖掘机技术哪家强(20)

    1032 挖掘机技术哪家强 20 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN Yue 为了用事实说明挖掘机技术到底哪家强 PAT组织了一场挖掘机技能大赛 现请你
  • maven仓库中_remote.repositories的作用

    首先直接给结论 remote repositories的作用是当maven本地仓库缓存了jar pom的情况下修改了maven的配置文件 settings xml 后依然会去远程仓库获取 以org slf4j slf4j api 1 5 6
  • 科创板、香港主板、纳斯达克三地部门上市条件和要求

    转自 https zhuanlan zhihu com p 69144513 科创板 香港主板 纳斯达克三地部门上市条件和要求 发布于 2019 06 14
  • 一、创建型模式:工厂方法模式(Factory Method)

    请MM去麦当劳吃汉堡 不同的MM有不同的口味 要每个都记住是一件烦人的事情 我一般采用Factory Method模式 带着MM到服务员那儿 说 要一个汉堡 具体要什么样的汉堡呢 让MM直接跟服务员说就行了 定义 核心工厂类不再负责所有产品
  • MySQL-多表关联

    多表关联 多张数据表之间是可以有一定的关联关系 这种关联关系可以通过外键约束实现 多表的分类 一对一 一对多 多对多 一对一 一张表对应另一张表 适用场景 人和身份证 一个人只能有一个身份证 一个身份证只能对应一个人 建表原则 在任意一个表
  • python爬虫实战练手——————淘宝网站的爬取

    python爬虫是很好的数据分析手段 可以进行爬虫程序来进行爬取网站 下面是淘宝的爬取 淘宝搜索书包 然后得到以下的界面 注意到下面的分页 可以通过进行分页的改变来进行多页数据的爬取 爬取多页 这里用到了和重要的re库 也就是正则表达式库
  • Windows10下Linux子系统Ubuntu使用教程(8)——升级WSL2,及解决遇到的问题

    WSL 2 是 WSL 中体系结构的新版本 它更改 Linux 发行版与 Windows 交互的方式 WSL 2 的主要目标是提高文件系统性能并增加系统调用的完全兼容性 每个 Linux 发行版都可以作为 WSL 1 或 WSL 2 发行版
  • vue 获取服务端base64位图片之后的处理

    目录 Base64是什么 Base64可以在Url中传输吗 Base64是加密算法么 Base64的应用场景有哪些 Base64的优点 Base64的缺点 关于vue中img无法展示base64位图片的原因分析 Base64是什么 Base
  • CSS-选择器的基本用法

    目录 一 CSS的分类 1 行内样式 2 内部样式 3 外部样式 二 选择器是什么 三 选择器具体种类 1 类选择器 2 标签选择器 3 ID选择器 4 通配符选择器 一 CSS的分类 1 行内样式 通过 style 属性 来指定某个标签的
  • Java实现Token的生成与验证

    二 基于JWT的token认证实现 JWT JSON Web Token 其实token就是一段字符串 由三部分组成 Header Payload Signature 1 引入依赖
  • 爬虫之简单js逆向

    本次js逆向没有存在代码混淆 所以还是比较简单的 重要的就是js逆向的思路 目标网站https notice qb com detail noticeId 215让我们开始吧 进入网站后按F12 查看DOC中的 可以看出该网页一部分内容是异
  • vue3解读—reactivity响应式实现

    前言 Vue3 中引入了proxy进行数据劫持 而effect是响应式系统的核心 而响应式系统又是 vue3 中的核心 所以vue3的解读要从 effect 开始讲起 1 reactivity和effect的使用 目前vue3的各个模块都可
  • 蓝桥杯:基础练习 特殊的数字(java实现)

    问题描述 153是一个非常特殊的数 它等于它的每位数字的立方和 即153 111 555 333 编程求所有满足这种条件的三位十进制数 输出格式 按从小到大的顺序输出满足条件的三位十进制数 每个数占一行 public class Main
  • 2014阿里巴巴9月14北京校园招聘笔试及参考答案

    form http blog csdn net lingfengtengfei article details 12344511 from http blog csdn net lingfengtengfei article details
  • java实现根据pdf文件模板生成pdf文件

    一 如何制作pdf模板 1 首先创建template doc 2 根据doc文件制作pdf模板 3 将doc文件输出为pdf 文件 gt 输出为pdf 4 输出的pdf文件 5 使用Adobe Acrobat DC打开template pd
  • HTML+CSS炫酷效果(小伙伴赶紧收藏起来吧)

    制作不易 点赞加关注哦 目录 1 实现奥运徽效果 2 实现3D效果 3 翻开葵花宝典 4 实现漂浮文字 动图 5 手机充电特效 动态 6 滚动时针 7 立体相册 1 实现奥运徽效果 由于图片违规 就不给老铁发了哈 亲自试试呗 HTML如下

随机推荐

  • 对 Electron 架构的理解

    Electron 的架构可以分为三层 Chromium Node js 和应用程序层 Electron 是一种基于 Chromium 和 Node js 的开源框架 可以用于快速构建跨平台的桌面应用程序 Chromium 层 Chromiu
  • 【并发编程】CPU cache结构和缓存一致性(MESI协议)

    一 cache cpu cache已经发展到了三级缓存结构 基本上现在买的个人电脑都是L3结构 1 cache的意义 为什么需要CPU cache 因为CPU的频率太快了 快到主存跟不上 这样在处理器时钟周期内 CPU常常需要等待主存 浪费
  • Klarf 文件可视化工具

    1 技术框架 1 1 前端 Vue3 网页版 Electron Quasar 可生成 EXE APK 等客户端 Element Plus 控件 axios 跨域 1 2 后端 Flask 提供接口 2 Web 版和客户端版 2 1 Web
  • android:configchanges 作用,关于android:configChanges的属性的简介

    在Android系统默认的情况下 当 屏幕方向 或 键盘显示隐藏 变化时都会销毁当前Activity 创建新的Activity 如果不希望重新创建Activity实例 可以在AndroidManifest xml中配置 android co
  • 基于Docker做MySQL主从搭建与Django的读写分离

    目录 基于Docker做MySQL主从搭建 django读写分离 基于Docker做MySQL主从搭建 主从的作用 写数据数据时使用主库 从库只用来读数据 这样做能够减少数据库压力 主从搭建可以一主一从 也可以是一主多从 mysql主从配置
  • 微信小程序、微信公众号、H5之间相互跳转

    转自慕课网 一 小程序和公众号 答案是 可以相互关联 在微信公众号里可以添加小程序 图片有点小 我把文字打出来吧 可关联已有的小程序或快速创建小程序 已关联的小程序可被使用在自定义菜单和模版消息等场景中 公众号可关联同主体的10个小程序及不
  • 反事实因果(Counterfactual)简介

    Counterfactual 简介 确定的反事实 反事实是什么 用了例子说明 比如你去了二仙桥 走的是成华大道 但是用了很久才到 于是你就想要是当初坐地铁就好了 你会发现 要是坐地铁就好了 这个推断只有在发生了 走成华大道用了很久 这个事实
  • 矩阵、向量求导

    1 行向量对元素求导 2 列向量对元素求导 例2 略 参考例1 把行向量转成列向量 分别对y向量的每个项进行求导 3 矩阵对元素求导 4 元素对行向量求导 5 元素对列向量求导 例5 略 参考例4 6 元素对矩阵求导 7 行向量对列向量求导
  • 在设计web页面时,为移动端设计一套页面,PC端设计一套页面,并且能自动根据设备类型来选择是用移动端的页面还是PC端的页面。

    响应式设计 即移动端和PC端共用一个HTML模式 网站的程序和模板自动根据设备类型和屏幕大小进行自适应调整 这种方法我不喜欢 原因是不能很好保证各种客户端的效果 里面存在各种复杂的兼容性等问题 我喜欢为不同的客户端写不同的模式 避免在响应式
  • Python开发就业岗位有哪些?Python薪资待遇如何?

    Python开发就业岗位有哪些 Python就业岗位分为 Python后端 数据分析 数据挖掘 机器学习 爬虫等 后端岗位多 Python岗位占50 是爬虫工程师的10倍 其次是数据分析岗位 仅次于Python后端开发 数据挖掘和机器学习大
  • linux下安装jenkins

    参考文档 如何在Linux CentOS7 环境搭建 Jenkins 服务器环境 爱码网 1 官网下载安装 官网 Redhat Jenkins Packages sudo wget O etc yum repos d jenkins rep
  • Linux安全扫描工具ClamAV安装及使用

    导语 Clam AntiVirus ClamAV 是免费而且开放源代码的防毒软件 软件与病毒码的更新皆由社群免费发布 ClamAV在命令行下运行 它不将杀毒作为主要功能 默认只能查出系统内的病毒 但是无法清除 需要用户自行对病毒文件进行处理
  • Csharp:WebClient and WebRequest use http download file

    Csharp WebClient and WebRequest use http download file 20140318 塗聚文收錄 string filePath 20140302 pdf string fileName http
  • Unity - 射线检测

    Unity 射线检测 本文简要分析了Unity中各类 射线检测 的基本原理及用法 及不同检测手段的性能对比 内容包括 Ray 射线 RaycastHit 光线投射碰撞信息 Raycast 光线投射 BoxCast SphereCast Ca
  • 学习黑马JVM的笔记

    JVM详解 一 JVM介绍 1 什么是JVM 2 有什么好处 3 学习路线 二 内存结构 1 程序计数器 Program Counter Registe 1 定义 2 作用 3 特点 4 演示 2 虚拟机栈 Java Virtual Mac
  • 通过socket获取对方ip地址

    struct sockaddr in sa int len sizeof sa if getpeername sockfd struct sockaddr sa len printf 对方IP s inet ntoa sa sin addr
  • GDI/GDI+/D2D/D3D

    GDI GDI D2D D3D 标签 GDID3D 2015 07 27 11 28 503人阅读 评论 0 收藏 举报 分类 Windows系统 7 原文链接 2D Drawing APIs in Windows 在 Windows 7
  • 微服务之服务网关(GateWay)

    服务网关 概述 什么是网关 为什么需要网关 GateWay实现网关 spring cloud 2 0 概念 Route 路由 工作流程 搭建 动态路由 Predicate 断言 注意 Filter 过滤 自定义过滤器 todo gatewa
  • 亲测有效!电脑系统自己停止或休眠了怎么办?如何禁止系统休眠断网?

    亲测有效 电脑系统自己停止或休眠了怎么办 如何禁止系统休眠断网 新安装的操作系统 在开启一段时间无人操作的情况下 经常发现电脑休眠了 或者网络断开了 这种情况如何解决 上干货 电脑休眠 睡眠问题 1 打开控制面板 找到 电源选项 2 更改电
  • 前端神器avalonJS入门(一)

    http www 360doc com content 14 1031 20 21412 421521791 shtml avalonJS是司徒正美开发和维护的前端mvvm框架 可以轻松实现数据的隔离和双向绑定 相比angularJS等前端