前面几节都是jquery界面方面的东西,本节研究些数据方面的东西:MVVM。

MVVM由三部分组成:Model <=> ViewModel <=> View,当Model数据改变时,通知所有与Model关联的View进行数据更新。

以vuejs一个简单例子实现为例:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Vue 测试实例</title>
  6. <script src="https://unpkg.com/vue/dist/vue.js"></script>
  7. </head>
  8. <body>
  9. <div id="app">
  10. <p>{{ message }}</p>
  11. </div>
  12.  
  13. <script>
  14. new Vue({
  15. el: '#app',
  16. data: {
  17. message: 'Hello Vue.js!'
  18. }
  19. })
  20. </script>
  21. </body>
  22. </html>

显示效果如下

现在模拟实现这一过程,ES5,6语法以前也没怎么接触,在网上翻看大神的资料,看到一篇实现相对较完整的
https://segmentfault.com/a/1190000016236834

根据他的实现原理本文进行了简化,只模拟实现绑定过程(不能拿来用于生产环境),稍微有点javascript基础的应该都能看懂。下次面试时面试官问你原理你说可以手写一个。

网上许多文章都是观察者,订阅者一堆名词,把读者都看晕了,其实核心代码就像下面这段代码这么简单.

  1. <body>
  2. <div id="app">
  3. <p>{{ message }}</p>
  4. <p>{{ message1 }}</p>
  5. </div>
  6. <div id="log"></div>
  7. <script>
  8. class JMVVM {
  9. constructor(p_obj) {
  10. this.init(p_obj);
  11. }
  12. init(p_obj) {
  13. $("#log").append("获取绑定对象初始化数据信息</br>");
  14. this.element = document.querySelector(p_obj.el);
  15. this.data = p_obj.data;
  16. $("#log").append("el:" + this.element.id + "</br>");
  17. for (let key in this.data) {
  18. let val = this.data[key];
  19. $("#log").append("key:" + key + "</br>");
  20. $("#log").append("1、给对象创建get,set方法</br>");
  21. let element=this.element;
  22. Object.defineProperty(this.data, key, {
  23. configurable: true,
  24. enumerable: true,
  25. get() {
  26. return val;
  27. },
  28. set(newVal) {
  29. val = newVal;
  30. let reg = eval("/{{([^}]*) "+key+" }}/g");
  31. // let reg1 = /{{([^}]*) +key+ }}/g;
  32. let match;
  33. $("#log").append("2、替换模板</br>");//模拟,只查找一级。
  34. element.childNodes.forEach(childNode=>{
  35. while ((match = reg.exec(childNode.textContent))) {
  36. childNode.textContent=val;
  37. }
  38. })
  39. // $("#log").append("2、替换模板</br>");
  40. // for(let children in element.childNodes)
  41. // while ((match = reg.exec(children.textContent))) {
  42. // children.textContent=val;
  43. // }
  44.  
  45. }
  46. });
           //触发set
  47. this.data[key] =val;
  48. }
  49.  
  50. }
  51. }
  52. </script>
  53. <script>
  54. // new Vue({
  55. // el: "#app",
  56. // data: {
  57. // message: "Hello Vue.js!"
  58. // }
  59. // });
  60. new JMVVM({
  61. el: "#app",
  62. data: {
  63. message1: "Hello JMVVM.js!"
  64. }
  65. });
  66. </script>
  67. </body>

执行结果如下

上面写法比较简单,只能替换一次,因为替换后{{ message }}就不存在了,那么就应该在第一次替换成功时候将对应元素缓存下来,具体怎么实现有多种方法,如果理解的不对,欢迎大家指正。

演示地址:www.jgui.com

注释:

ES6 新增了let命令,用来声明局部变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。

后续:ES6对IE兼容性挺差的,如果是客户习惯使用低版本IE的话,尽量不要使用ES6或者让客户更换浏览器。

JGUI源码:实现简单MVVM单项绑定学习笔记(15)的更多相关文章

  1. jQuery源码分析_工具方法(学习笔记)

    expando:生成唯一JQ字符串(内部使用) noConflict():防止冲突 isReady:DOM是否加载完成(内部) readyWait:等待多少文件的计数器(内部) holdReady() ...

  2. zepto源码--核心方法(类数组相关)--学习笔记

    从这篇起,在没有介绍到各类插件之前,后面将陆续介绍zepto对外暴露的核心方法.即$.fn={}里面的所有方法的介绍.会配合zepto的API进行介绍. 其实前面已经介绍了几个,如width,heig ...

  3. JGUI源码:从头开始,建一个自己的UI框架(1)

    开篇 1.JGUI是为了逼迫自己研究底层点的前端技术而做的框架,之前对web底层实现一直没有深入研究,有了技术瓶颈,痛定思痛从头研究, 2.虽然现在vue技术比较火,但还在发展阶段,暂时先使用JQue ...

  4. Vue源码解析---数据的双向绑定

    本文主要抽离Vue源码中数据双向绑定的核心代码,解析Vue是如何实现数据的双向绑定 核心思想是ES5的Object.defineProperty()和发布-订阅模式 整体结构 改造Vue实例中的dat ...

  5. JGUI源码:鼠标中键滚动再次优化(5)

    //电脑端中键滚动事件 var mousewheel = getBrowserInfo() == "Firefox" ? "DOMMouseScroll" : ...

  6. 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换

    路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)   MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...

  7. 从源码来理解slf4j的绑定,以及logback对配置文件的加载

    项目中的日志系统使用的是slf4j + logback.slf4j作为一个简单日志门面,为各种loging APIs(像java.util.logging, logback, log4j)提供一个简单 ...

  8. JGUI源码:Accordion鼠标中键滚动和手机端滑动实现(2)

    本文是抽屉组件在PC端滚动鼠标中键.手机端滑动时,滚动数据列表实现方法,没有使用iscroll等第三方插件,支持火狐,谷歌,IE8+等浏览器. 演示在:www.jgui.com Github地址:ht ...

  9. (二十三)原型模式详解(clone方法源码的简单剖析)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 原型模式算是JAVA中最简单 ...

随机推荐

  1. go的生产者-消费者模式

    package main import ( "fmt" "math/rand" "time" ) // 数据生产者 func produce ...

  2. C语言字符数组回顾

    赋值篇: Part1      错误引例*2: char c6[];//WRONG c6="HELLO";//WRONG char c7[];//WRONG c7[]='H';// ...

  3. Docker-Linux环境安装

    不同服务器操作系统安装命令不同,例如centOS默认用yum,Ubuntu可能默认用apt-get.这里推荐一种安装方式,通过下载shell脚本 https://get.docker.com,会检测操 ...

  4. shell脚本-正则、grep、sed、awk

    ----------------------------------------正则---------------------------------------- 基础正则 ^word ##搜索以w ...

  5. Conway生命游戏

    版权申明:本文为博主窗户(Colin Cai)原创,欢迎转帖.如要转贴,必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/9986679.html 作者:窗户 Q ...

  6. oracle有三种类型的异常错误: 预定义 ( Predefined )错误里面的常见错误

    oracle有三种类型的异常错误: 预定义 ( Predefined )错误, 非预定义 ( Predefined )错误, 用户定义(User_define) 错误 预定义 ( Predefined ...

  7. Elastic Stack-Elasticsearch使用介绍(五)

    一.前言     前4篇将Elasticsearch用法的API和原理方面东西介绍了一下,相信大家对Elasticsearch有了一定的认知,接下我们主要从索引的建立到后期的一些优化做一些介绍: 二. ...

  8. IDEA导入项目jar包红线、依赖问题....

    一般遇到这种情况用以下两种方式解决....... 1.reimport包 2.清缓存重启 针对1方法: a.确实不缺包: 可以先注释掉pom文件中的jar包, 此时idea会提示import, 那就i ...

  9. C#-之属性(1)

    1. 属性定义方式与字段类似,但还包括Set和Get两个访问器,其格式如下: public/private <type> Name { get { return variable:    ...

  10. Nginx 在线新增模块

    系统:Centos7.5 Nginx版本:1.12.2 今天给项目添加ssl证书时,发现nginx 竟然不支持ssl,经过查看,询问相关人员发现nginx编译的时候没有任何模块(历史原因).哎.... ...