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 相关文章推荐
js实现在字符串中提取数字
Nov 05 Javascript
jQuery动态星级评分效果实现方法
Aug 06 Javascript
jquery实现很酷的网页顶部图标下拉菜单效果
Aug 22 Javascript
js中获取时间new Date()的全面介绍
Jun 20 Javascript
浅谈js中的in-for循环
Jun 28 Javascript
Vue.js组件tree实现无限级树形菜单
Dec 02 Javascript
jQuery向webApi提交post json数据
Jan 16 Javascript
基于jQuery的表单填充实例
Aug 22 jQuery
vue表单自定义校验规则介绍
Aug 28 Javascript
判断iOS、Android以及PC端的示例代码
Nov 15 Javascript
用Vue.js方法创建模板并使用多个模板合成
Jun 28 Javascript
js实现弹窗效果
Aug 09 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
织梦模板标记简介
2007/03/11 PHP
php学习之数据类型之间的转换代码
2011/05/29 PHP
解析php多线程下载远程多个文件
2013/06/25 PHP
Laravel源码解析之路由的使用和示例详解
2018/09/27 PHP
微信公众平台开发教程④ ThinkPHP框架下微信支付功能图文详解
2019/04/10 PHP
ThinkPHP5&amp;5.1框架关联模型分页操作示例
2019/08/03 PHP
Javascript this关键字使用分析
2008/10/21 Javascript
Prototype String对象 学习
2009/07/19 Javascript
jQuery的三种$()
2009/12/30 Javascript
jquery animate图片模向滑动示例代码
2011/01/26 Javascript
js 编程笔记 无名函数
2011/06/28 Javascript
jQuery实现炫酷的鼠标轨迹特效
2015/02/01 Javascript
JS实现仿QQ聊天窗口抖动特效
2015/05/10 Javascript
Bootstrap整体框架之JavaScript插件架构
2016/12/15 Javascript
Angular ui-roter 和AngularJS 通过 ocLazyLoad 实现动态(懒)加载模块和依赖
2018/11/25 Javascript
NodeJs 文件系统操作模块fs使用方法详解
2018/11/26 NodeJs
详解mpvue中使用vant时需要注意的onChange事件的坑
2019/05/16 Javascript
vue操作dom元素的3种方法示例
2020/09/20 Javascript
[02:39]DOTA2英雄基础教程 天怒法师
2013/11/29 DOTA
Python Web服务器Tornado使用小结
2014/05/06 Python
Saltstack快速入门简单汇总
2016/03/01 Python
Python基础篇之初识Python必看攻略
2016/06/23 Python
python 文件操作api(文件操作函数)
2016/08/28 Python
Python使用gRPC传输协议教程
2018/10/16 Python
python 多线程将大文件分开下载后在合并的实例
2018/11/09 Python
一文带你了解Python中的字符串是什么
2018/11/20 Python
python中resample函数实现重采样和降采样代码
2020/02/25 Python
Python如何输出百分比
2020/07/31 Python
python使用dlib进行人脸检测和关键点的示例
2020/12/05 Python
Oakley西班牙官方商店:太阳眼镜和男女运动服
2019/04/26 全球购物
北美女性服装零售连锁店:maurices
2019/06/12 全球购物
介绍一下Python中webbrowser的用法
2013/05/07 面试题
澳大利亚商务邀请函
2014/01/17 职场文书
2014年高考决心书
2014/03/11 职场文书
二年级班级文化建设方案
2014/05/10 职场文书
化工专业自荐书
2014/06/16 职场文书