js实现一个简单的MVVM框架示例


Posted in Javascript onJanuary 15, 2018

以前都是默默地看园子里的文章,猥琐的点赞,今天也分享一下自己用js实现的一个简单mvvm框架。

最初只做了自动绑定事件,后面又参考学习了vue,knouckout以及argular实现方式,以及结合自己做WPF的一些经验,增加了属性绑定,今天又稍微整理了下,完善了部分功能,把代码提交到了码云:https://gitee.com/zlj_fy/Simple-MVVM

先简单介绍下用法:

<form class="form-horizontal" role="form" data-context="TestController">
  <div class="form-group">
   <legend>Form title</legend>
  </div>
  <div class="form-group">
   <div class="col-sm-6 col-sm-offset-2">
    <input type="text" class="form-control" bind-val="age,format=format" style="margin:5px 0" />
    <input type="text" class="form-control" bind-val="desc" style="margin:5px 0" />
    <input type="range" min="10" max="300" bind-val="age" step="10" class="form-control" style="margin:5px 0" />
    <input type="button" class="btn btn-primary" value="更新" style="margin:5px 0" on-click="update" />
   </div>
  </div>
 </form>
 <script>
  var TestController = {
   data: {
    name: 'xiaoming',
    age: 3,
    desc: function() {





return this.name + ' likes looking little movie. he should take care of his body' 
    }
   },
   format: function(val) {
    return val + '岁'
   },
   update: function() {
    this.name = 'this is a test'
    this.age = 18
   }
  }
  $('body').controller()
 </script>

首先定义一个控制器,可以是json对象,也可一是一个function,然后在顶层的元素定义data-context=“[控制器名称]”就可以将该控制器绑定到该节点底下所有元素。如果元素后代存在嵌套Controller,则其所在的元素以下子元素作用域指向子控制器。

1.监控属性以及复杂属性

所有属性必须定义在data节点下,如果里面的属性定义成function则认为是复杂属性(例如desc),复杂属性是只读的,重新赋值的话会提示错误。

绑定到html元素上的格式:"{属性名,fomat=[控制器方法]}",属性名支持嵌套属性,例如(a.b);属性名不支持表达式,考虑了觉得不是很有必要,完全可以使用复杂属性去代替,当前缺点是业务复杂的话可能造成大量复杂属性;属性名右边是可选参数,目前只有format,也就是属性显示在html上的转换方法。

2.指令

绑定指令语法是 bind-{指令}的形式,目前只实现了val,attr,text,html,template,其实可以看出,前面4个都只是简单封装了jqeury方法,template是用到了jquery-tmpl插件实现的,如果你需要更多的指令,你可以自己去扩展,只需要实现init初始加载方法(接收当前的observer参数),以及update方法(参数说明:对应的jquery元素,最新的值,当前控制器实例);如果是扩展已有的指令,默认会覆盖原有的。如下:

$.controller.addDirective("val", {
  init: function (observer) {
   if (observer.$ele.is('input,select')) {
    //监听onchange事件
    observer.$ele.on('input propertychange', function () {
     var newVal = $(this).val()
     observer.writeValue(newVal)
    })
   }
  },
  update: function ($ele, newVal, controller) {
   $ele.val && $ele.val(newVal)
  }
 })

3.事件

绑定事件语法:on-{事件}=“{控制器方法},type=on/one”,控制器方法右边是可选参数,目前只有绑定类型on/one,默认是on;控制器方法接收两个参数,一个是可在对应事件的元素上设置初始参数,一个是event事件参数;

<button type="button" class="btn btn-primary" data-page="1" on-click="refesh">查询</button>

4.方法

直接使用this.属性名,就可以直接访问对应data节点下的属性。

5.钩子

init以及created,init是在监听所有属性之后编译dom之前,可以在这方法上初始化参数;created是编译dom元素之后。

其中控制器默认实现了extend继承方法,可以继承另一个控制器,必须在init方法中使用。当前你也可以自己使用原型继承的方式去实现。

init: function () {
    this.extend(PageController)
   },
   created: function () {
    //TODO
   },

6.扩展

相信大家在做项目的时候肯定都会有一套公用的组件,那么可以像下面那样扩展,默认对应的组件挂载到所有的控制器示例下面,就可以之间在对应的方法下直接调用了: this.http.post();

不过有一个建议,就是尽量统一将回调方法的作用域指向控制器,这样开发不至于老是出现作用域的问题。

$.controller.extend({
   utils: utils,
   notify: $.notify,
   modal: $.modal,
   http: $.http,
   alert: $.alert
  })

7.原理以及代码分析(待续...)

整个js代码量只有300多行,所以实现的比较简单,有很多方面是没有考虑到的,还有一些功能是想实现却没有去做的,目前不支持数组变化检测,以及局部更新相关dom。

以上这篇js实现一个简单的MVVM框架示例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
B/S开发中常用javaScript技术与代码
Mar 09 Javascript
在IE,Firefox,Safari,Chrome,Opera浏览器上调试javascript
Dec 02 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
Oct 26 Javascript
纯JS实现可拖拽表单的简单实例
Sep 02 Javascript
KnockoutJS 3.X API 第四章之数据控制流component绑定
Oct 10 Javascript
基于jQuery实现表格的排序
Dec 02 Javascript
Node.js实现连接mysql数据库功能示例
Sep 15 Javascript
原生js封装运动框架的示例讲解
Oct 01 Javascript
vue实现手机号码抽奖上下滚动动画示例
Oct 18 Javascript
为输入框加入数字js校验代码分享
Nov 02 Javascript
详解vue移动端项目代码拆分记录
Mar 15 Javascript
JS学习笔记之闭包小案例分析
May 29 Javascript
详解angularjs 学习之 scope作用域
Jan 15 #Javascript
高性能的javascript之加载顺序与执行原理篇
Jan 14 #Javascript
关于axios如何全局注册浅析
Jan 14 #Javascript
Vue+Flask实现简单的登录验证跳转的示例代码
Jan 13 #Javascript
react-redux中connect的装饰器用法@connect详解
Jan 13 #Javascript
基于vue实现网站前台的权限管理(前后端分离实践)
Jan 13 #Javascript
详解webpack-dev-server使用http-proxy解决跨域问题
Jan 13 #Javascript
You might like
手冲咖啡应该是现代精品咖啡店的必备选项吗?
2021/03/03 冲泡冲煮
php的chr和ord函数实现字符加减乘除运算实现代码
2011/12/05 PHP
php实现scws中文分词搜索的方法
2015/12/25 PHP
php中的抽象方法和抽象类
2017/02/14 PHP
mac pecl 安装php7.1扩展教程
2019/10/17 PHP
一实用的实现table排序的Javascript类库
2007/09/12 Javascript
基于jquery的无限级联下拉框js插件
2011/10/29 Javascript
JS动态添加与删除select中的Option对象(示例代码)
2013/12/25 Javascript
Javascript中的几种URL编码方法比较
2015/01/23 Javascript
Vue插件写、用详解(附demo)
2017/03/20 Javascript
AngularJS自定义指令之复制指令实现方法
2017/05/18 Javascript
Vue CLI3搭建的项目中路径相关问题的解决
2018/09/17 Javascript
微信小程序实现banner图轮播效果
2020/06/28 Javascript
vue+Element实现搜索关键字高亮功能
2019/05/28 Javascript
JavaScript实现打砖块游戏
2020/02/25 Javascript
微信小程序收藏功能的实现代码
2020/06/19 Javascript
通过实例解析chrome如何在mac环境中安装vue-devtools插件
2020/07/10 Javascript
js实现金山打字通小游戏
2020/07/24 Javascript
[01:06:12]VP vs NIP 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
[59:42]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
[01:11:46]DOTA2-DPC中国联赛 正赛 iG vs Magma BO3 第一场 2月23日
2021/03/11 DOTA
Python爬虫代理IP池实现方法
2017/01/05 Python
Python中几种导入模块的方式总结
2017/04/27 Python
python实现信号时域统计特征提取代码
2020/02/26 Python
利用CSS3实现的文字定时向上滚动
2016/08/29 HTML / CSS
CSS3 实现时间轴动画
2020/11/25 HTML / CSS
HTML5中图片之间的缝隙完美解决方法
2017/07/07 HTML / CSS
HTML5新特性之语义化标签
2017/10/31 HTML / CSS
详解如何将 Canvas 绘制过程转为视频
2021/01/25 HTML / CSS
英格兰橄榄球商店:England Rugby Store
2016/12/17 全球购物
上海期货面试题
2014/01/31 面试题
成人大专生实习期的自我评价
2013/10/02 职场文书
常务副总经理岗位职责
2014/04/12 职场文书
小学优秀辅导员事迹材料
2014/05/11 职场文书
元旦趣味活动方案
2014/08/22 职场文书
2015最新学生自我评价范文
2015/03/03 职场文书