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 相关文章推荐
Jquery getJSON方法详细分析
Dec 26 Javascript
javascript history对象(历史记录)使用方法(实现浏览器前进后退)
Jan 07 Javascript
js 与 php 通过json数据进行通讯示例
Mar 26 Javascript
JavaScript字符串常用类使用方法汇总
Apr 14 Javascript
详解JavaScript中Date.UTC()方法的使用
Jun 12 Javascript
javascript字符串替换函数如何一次性全部替换掉
Oct 30 Javascript
vue 页面加载进度条组件实例
Feb 05 Javascript
小程序scroll-view组件实现滚动的示例代码
Sep 20 Javascript
angularjs通过过滤器返回超链接的方法
Oct 26 Javascript
layui 解决form表单点击无反应的问题
Oct 25 Javascript
node.js使用http模块创建服务器和客户端完整示例
Feb 10 Javascript
JS绘图Flot如何实现可选显示曲线图功能
Oct 16 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
新52大事件
2020/03/03 欧美动漫
php下用cookie统计用户访问网页次数的代码
2010/05/09 PHP
PHP中Session引起的脚本阻塞问题解决办法
2014/04/08 PHP
php生成QRcode实例
2014/09/22 PHP
一个符号插入器 中用到的js代码
2007/09/04 Javascript
js用正则表达式来验证表单(比较齐全的资源)
2013/11/17 Javascript
浅谈JS正则表达式的RegExp对象和括号的使用
2016/07/28 Javascript
Bootstrap轮播插件使用代码
2016/10/11 Javascript
js利用appendChild对标签进行排序的实现方法
2016/10/16 Javascript
AngularJS使用ng-repeat和ng-if实现数据的删选显示效果示例【适用于表单数据的显示】
2016/12/13 Javascript
JavaScript 函数节流详解及方法总结
2017/02/09 Javascript
详解node nvm进行node多版本管理
2017/10/21 Javascript
webpack4 SCSS提取和懒加载的示例
2018/09/03 Javascript
Vue注册组件命名时不能用大写的原因浅析
2019/04/25 Javascript
jquery实现动态改变css样式的方法分析
2019/05/27 jQuery
实用Javascript调试技巧分享(小结)
2019/06/18 Javascript
JS实现移动端可折叠导航菜单(现代都市风)
2020/07/07 Javascript
linux平台使用Python制作BT种子并获取BT种子信息的方法
2017/01/20 Python
使用Python对SQLite数据库操作
2017/04/06 Python
Pytorch使用MNIST数据集实现CGAN和生成指定的数字方式
2020/01/10 Python
keras使用Sequence类调用大规模数据集进行训练的实现
2020/06/22 Python
python集合的新增元素方法整理
2020/12/07 Python
python中slice参数过长的处理方法及实例
2020/12/15 Python
CSS3 Calc实现滚动条出现页面不跳动问题
2017/09/14 HTML / CSS
医生实习工作总结的自我评价
2013/09/27 职场文书
学生爱国演讲稿
2014/01/14 职场文书
《沉香救母》教学反思
2014/04/19 职场文书
初二学习计划书范文
2014/04/27 职场文书
煤矿开采专业求职信
2014/07/08 职场文书
优秀员工推荐材料
2014/12/20 职场文书
纪委立案决定书
2015/06/24 职场文书
2015年幼儿园国庆节活动总结
2015/07/30 职场文书
2016大学生国家助学贷款承诺书
2016/03/25 职场文书
jQuery实现影院选座订座效果
2021/04/13 jQuery
apache ftpserver搭建ftp服务器
2022/05/20 Servers
类和原型的设计模式之复制与委托差异
2022/07/07 Javascript