欢迎大家指导与讨论 : )

  前言

    关于MVVM的原理大家可以参考这篇文章。《【翻译】Object.observe()带来的数据绑定变革 》http://www.tuicool.com/articles/ZVVNBv。

    文章中的代码为笔者实践时写的小demo,可以运行。

  代码

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<title>Document</title>
</head> <body> <div id="app">
<h1>作用域A</h1>
<input type="text" two-way-bind="test">
<h1 bind="test"></h1>
</div>
<hr /> <div id="apple">
<h1>作用域B</h1>
<input type="text" two-way-bind="test">
<h1 bind="test"></h1>
</div>
<hr /> <script type="text/javascript">
// vm -> view model; v -> view
// 自定义两个绑定“指令”一个是从vm->v的绑定,一个是双向绑定
var directive_bind = ['bind', 'two-way-bind'];
// 常量 声明该类型仅仅是vm->v 的DOM渲染
var DOM = 'DOM'
// 常量 声明该类型是双向绑定
var TWOWAY = 'TWOWAY'
// 新增两个作用域,用的是元素ID
var vm = new mvvm('app');
var vm2 = new mvvm('apple') // 这是一个构造函数
// 用来返回一个可以被监测变化、有固定范围的vm
function mvvm(rootEle) {
this.scope = rootEle
// 监听vm
observe(this)
// 确定作用域 —— 同时为v -> vm做事件监听
fineScope(this)
} function observe(vm) {
// 监听vm对象模型的改变
Object.observe(vm, function(changes) {
changes.forEach(function(change, i) {
switch (change.type) {
case 'add':
fineScope(vm)
break;
case 'delete':
fineScope(vm);
break;
case 'update':
fineScope(vm);
break;
default:
break;
}
})
})
} // vm的改变引起v的改变 此处是 vm -> v
function updateView(ele, value, type) {
if (type === DOM) {
if (value) {
ele.innerHTML = value
} else {
ele.innerHTML = ''
} } else if (type == TWOWAY) {
if (value) {
ele.value = value
} else {
ele.value = ''
}
}
} function fineScope(vm) {
var vmRootEle = document.getElementById(vm.scope)
// 递归遍历该作用域下的所有DOM
findChild(vmRootEle, vm)
} function findChild(ele, vm) {
// 查找所有自定义属性:bind、two-way-bind
for (var i = 0; i < directive_bind.length; i++) {
// 如果DOM有我们的自定义绑定属性
if (ele.getAttribute(directive_bind[i]) && directive_bind[i] === 'bind') {
// 则按 vm->v的方向进行渲染
updateView(ele, vm[ele.getAttribute('bind')], DOM)
} else if (ele.getAttribute(directive_bind[i]) && directive_bind[i] === 'two-way-bind') {
var attr = ele.getAttribute('two-way-bind')
// 同理
updateView(ele, vm[attr], TWOWAY)
// 有点不同,这里是双向绑定,需要为该DOM增加事件监听
twoWayBind(ele, attr, vm)
}
}
// 递归遍历
if (ele.hasChildNodes()) {
var sonNodes = ele.childNodes;
for (var j = 0; j < sonNodes.length; j++) {
if (sonNodes[j].nodeType === 1) {
findChild(sonNodes[j], vm)
}
}
}
} function twoWayBind(ele, prop, vm) {
// 局限性:本DOM只是用了input[text],如果要监听其他input[x]应该要用对应的监听方法
ele.oninput = function() {
vm[prop] = ele.value
}
}
</script>
</body> </html>

原生JS实现MVVM模式的更多相关文章

  1. 由项目浅谈JS中MVVM模式

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.    背景 最近项目原因使用了durandal.js和knock ...

  2. js架构设计模式——由项目浅谈JS中MVVM模式

    1.    背景 最近项目原因使用了durandal.js和knockout.js,颇有受益.决定写一个比较浅显的总结. 之前一直在用SpringMVC框架写后台,前台是用JSP+JS+标签库,算是很 ...

  3. 原生JS:严格模式详解

    严格模式 本文参考MDN做的详细整理,方便大家参考[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript) 设计目的 设立”严格模式 ...

  4. dynamic-css 动态 CSS 库,使得你可以借助 MVVM 模式动态生成和更新 css,从 js 事件和 css 选择器的苦海中脱离出来

    dynamic-css 使得你可以借助 MVVM 模式动态生成和更新 css,从而将本插件到来之前,打散.嵌套在 js 中的修改样式的代码剥离出来.比如你要做元素跟随鼠标移动,或者根据滚动条位置的变化 ...

  5. 使用单体模式设计原生js插件

    ----------基于上次写的jquery插件进行改造  http://www.cnblogs.com/GerryOfZhong/p/5533773.html 背景:jQuery插件依赖jQuery ...

  6. 浅谈MVVM模式和MVP模式——Vue.js向

    浅谈MVVM模式和MVP模式--Vue.js向 传统前端开发的MVP模式 MVP开发模式的理解过程 首先代码分为三层: model层(数据层), presenter层(控制层/业务逻辑相关) view ...

  7. js架构设计模式——MVVM模式下,ViewModel和View,Model有什么区别

    MVVM模式下,ViewModel和View,Model有什么区别 Model:很简单,就是业务逻辑相关的数据对象,通常从数据库映射而来,我们可以说是与数据库对应的model. View:也很简单,就 ...

  8. 抛弃JQ,回归原生js……

    之前我写过一篇文章叫做<jq不会被淘汰>--而事实上它真的不会被淘汰,因为即使在mvvm框架盛行的今天,原生js的api越来越友好的今天,jq依然在用户量上是霸主-- 但是今天我们要讨论的 ...

  9. Vue.js 和 MVVM 的小细节

    Vue.js 和 MVVM 的小细节 转载 作者:流云诸葛 链接:www.cnblogs.com/lyzg/p/6067766.html MVVM 是Model-View-ViewModel 的缩写, ...

随机推荐

  1. 使用MyEclipse 开发struts2框架结构详细教程——以登录为例

    1.首先建立Web Project,名称为:struts2 ,然后选择Java EE6.0,点击Finish. 2.右击“struts”选择MyEclipse->Add Struts Capab ...

  2. iOS 根据字符串数目,自定义Label等控件的高度

    利用分类,NSString,增加一个方法. #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interfa ...

  3. SharePoint 2013 状态机工作流之扩展自定义状态

    当我们使用SharePoint 2013的状态机工作流时,发现一个非常不爽的事情,就是SharePoint 所有的工作流状态,都是固定的那些,没办法显示我们自定义的状态,后来经过Google发现,原来 ...

  4. android 多线程

    本章讲述在android开发中,多线程的应用.多线程能够处理耗时的操作并优化程序的性能.本章主要介绍知识点,AsyncTask,Java线程池,ThreadPoolExecutor线程池类.本章案例只 ...

  5. jQuery与Zepto的异同

    一,同: Zepto最初是为移动端开发的库,是jQuery的轻量级替代品,因为它的API和jQuery相似,而文件更小.Zepto最大的优势是它的文件大小,只有8k多,是目前功能完备的库中最小的一个, ...

  6. 请问utf-8的中文是一个汉字占三个字节长度吗?

    这是个好问题,可以当作一个笔试题.先从字符编码讲起. 1.美国人首先对其英文字符进行了编码,也就是最早的ascii码,用一个字节的低7位来表示英文的128个字符,高1位统一为0: 2.后来欧洲人发现尼 ...

  7. Javascript如何实现AOP

    简介: AOP(面向切面的编程)是为了解决功能的独立性与可维护性而提供的一种编程思想.当多个函数大量重复使用同一个功能时通过分层切分,将功能平衡的划分,从而提高低耦合性. JS中实现: index.h ...

  8. C#的HTTP开发包 HttpLib

    HttpLib 可以用来简化在 C# 应用中异步的访问 Web 服务的操作.同时包含文件上传和访问网页的方法. 支持: GET POST Form Encoded Multipart File Upl ...

  9. JDK1.3安装出现/lib/ld-linux.so.2: bad ELF interpreter: No such file or directory Done.

    今天是出道以来第一次安装JDK1.3,大学的时候接触的也已是JDK1.4,而且是在Red Hat Enterprise Linux Server release 6.6上,安装JDK1.3是由于软件组 ...

  10. 关于一个sql的优化分析

    应用这边新上线了一个查询,正在跑,让我看下状态以及分析下能不能再快点. 如下sql: SELECT x.order_no , order_date+7/24 AS order_date, addres ...