MVVM的理解

MVVM拆开来即为Model-View-ViewModel,有View,ViewModel,Model三部分组成。View层代表的是视图、模版,负责将数据模型转化为UI展现出来。Model层代表的是模型、数据,可以在Model层中定义数据修改和操作的业务逻辑。ViewModel层连接Model和View。

在MVVM的架构下,View层和Model层并没有直接联系,而是通过ViewModel层进行交互。ViewModel层通过双向数据绑定将View层和Model层连接了起来,使得View层和Model层的同步工作完全是自动的。因此开发者只需关注业务逻辑,无需手动操作DOM,复杂的数据状态维护交给MVVM统一来管理。在Vue.js中MVVM的体现:

MVVM的原理

在不同的框架当中,MVVM实现的原理是不同的:

脏检查机制:

Angular.js就是采取的脏检查机制,当发生了某种事件(例如输入),Angular.js会检查新的数据结构和之前的数据结构是否发生来变动,来决定是否更新视图。

数据劫持

Vue.js的实现方式,对数据(Model)进行劫持,当数据变动时,数据会出发劫持时绑定的方法,对视图进行更新。

相同点

脏检查机制和数据劫持是有许多相同点的,例如,它们都有三个步骤:

  • 解析模版
  • 解析数据
  • 绑定模版与数据

实现MVVM

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Two-way data-binding</title>
</head>
<body><div id="app"><input type="text" v-model="text">{{ text }}</div><script>function observe (obj, vm) {Object.keys(obj).forEach(function (key) {defineReactive(vm, key, obj[key]);});}function defineReactive (obj, key, val) {var dep = new Dep();Object.defineProperty(obj, key, {get: function () {if (Dep.target) dep.addSub(Dep.target);return val},set: function (newVal) {if (newVal === val) returnval = newVal;dep.notify();}});}function nodeToFragment (node, vm) {var flag = document.createDocumentFragment();var child;while (child = node.firstChild) {compile(child, vm);flag.appendChild(child);}return flag;}function compile (node, vm) {var reg = /\{\{(.*)\}\}/;// 节点类型为元素if (node.nodeType === 1) {var attr = node.attributes;// 解析属性for (var i = 0; i < attr.length; i++) {if (attr[i].nodeName == 'v-model') {var name = attr[i].nodeValue; // 获取v-model绑定的属性名node.addEventListener('input', function (e) {// 给相应的data属性赋值,进而触发该属性的set方法vm[name] = e.target.value;});node.value = vm[name]; // 将data的值赋给该nodenode.removeAttribute('v-model');}}new Watcher(vm, node, name, 'input');}// 节点类型为textif (node.nodeType === 3) {if (reg.test(node.nodeValue)) {var name = RegExp.$1; // 获取匹配到的字符串name = name.trim();new Watcher(vm, node, name, 'text');}}}function Watcher (vm, node, name, nodeType) {//  this为watcher函数Dep.target = this;//  console.log(this);this.name = name;this.node = node;this.vm = vm;this.nodeType = nodeType;this.update();Dep.target = null;}Watcher.prototype = {update: function () {this.get();if (this.nodeType == 'text') {this.node.nodeValue = this.value;}if (this.nodeType == 'input') {this.node.value = this.value;}},// 获取daa中的属性值get: function () {this.value = this.vm[this.name]; // 触发相应属性的get}}function Dep () {this.subs = []}Dep.prototype = {addSub: function(sub) {this.subs.push(sub);},notify: function() {this.subs.forEach(function(sub) {sub.update();});}};function Vue (options) {this.data = options.data;var data = this.data;observe(data, this);var id = options.el;var dom = nodeToFragment(document.getElementById(id), this);// 编译完成后,将dom返回到app中document.getElementById(id).appendChild(dom);}var vm = new Vue({el: 'app',data: {text: 'hello world'}});</script>
</body>
</html>
复制代码

Vue.js中的MVVM相关推荐

  1. echarts怎么用在php,在Vue.JS中怎样使用echarts

    这次给大家带来在Vue.JS中怎样使用echarts,在Vue.JS中使用echarts的注意事项有哪些,下面就是实战案例,一起来看一下. 上篇文章给大家介绍了 在 webpack 中使用 EChar ...

  2. vue.js中mock本地json数据

    vue.js中mock本地json数据 新版本的vue项目中已经将dev-server.js,dev-client.js两个js文件合并到了webpack.dev.conf.js文件中,以下分别是新旧 ...

  3. VUE.js 中取得后台原生HTML字符串 原样显示问题

    今天使用vue调试页面,发现了页面上的一个问题,后台数据传过来的HTML字符串并没有被转换为正常的HTML代码,一拍脑门,发现忘记转换了,于是满心欢喜加上了{{{}}}.但是之后构建发现报错: 为此去 ...

  4. php动态写入vue,Vue.js中使用动态组件的方法

    本文介绍了如何在Vue.js中引用组件中的HTML元素.您可以通过使用Vue路由器或创建动态组件来切换视图或组件模板. Vue路由器用于在DOM中的视图或组件模板之间导航.要使用Vue路由器,请在ro ...

  5. 浅析Vue.js 中的条件渲染指令

    1 应用于单个元素 Vue.js 中的条件渲染指令可以根据表达式的值,来决定在 DOM 中是渲染还是销毁元素或组件. html: <div id="app"> < ...

  6. html5怎么改为vue_是否还在疑惑Vue.js中组件的data为什么是函数类型而不是对象类型...

    点击上方"前端印象",选择"设为星标"第一时间关注技术干货! 引言 要理解本篇文章,必须具备JavaScript中基本数据类型和引用数据类型的概念,大家可以花两 ...

  7. ie浏览器查看vue中js_浅析 Vue.js 中那些空间换时间的操作

    Hello,各位小伙伴,接下来的一段时间里,我会把我的课程<Vue.js 3.0 核心源码解析>中问题的答案陆续在我的公众号发布,由于课程的问题大多数都是开放性的问题,所以我的答案也不一定 ...

  8. 在vue.js中实现a标签href tel的打电话功能

    在vue.js中实现a标签href tel的打电话功能 div v-for="p in persons"> <p> name: {{ p.name }} < ...

  9. Vue.js中的v-model指令(双向绑定)

    Vue.js中v-model的作用 v-model的作用和使用场景 1.v-model的作用--双向绑定 2.v-model双向绑定的使用场景--表单 3.总结 v-model的作用和使用场景 你好! ...

最新文章

  1. Python计算数据相关系数(person、Kendall、spearman)
  2. 他是阿里 P11,靠写代码写成合伙人,身家几十亿,没有他,我们可能刷不了淘宝!...
  3. android 地图服务开发 INSTALL_FAILED_MISSING_SHARED_LIBRARY 错误解决
  4. 【Paper】2021_Observer-based distributed consensus for multi-agent systems with directed networks and
  5. 在linux下安装JDK
  6. hibernate实体的几种状态:
  7. 使用FizzBu​​zz和Mockito进行单元测试
  8. Apache Shiro第3部分–密码学
  9. linux shell中各种分号和括号,linux shell 各种分号,括号使用方法总结
  10. Linux 服务器惊现比特币勒索事件,腾讯云安全专家来支招
  11. python语言程序设计 梁勇_计算机二级教程 Python语言程序设计,第9章Python标准库概览...
  12. linux中断机制--理解中断上半部/下半部、软中断、tasklet、工作队列(可调度、可睡眠)
  13. AI YOLO目标检测算法
  14. 【PCB设计工具】在线 mil到mm单位转换、mm到mils换算
  15. 新网站如何做seo优化,这5个步骤让网站快速被收录
  16. 转:软件开发的葵花宝典
  17. Android 自定义锁屏的实现
  18. 真!一文搞定 HTTP 和 HTTPS
  19. Software Performance Testing - 全链路压测知识点整理
  20. 计算机开机滴一声513错误,电脑滴一声开不了机怎么办_电脑一声响后就开不了机了的处理办法...

热门文章

  1. Android中Application类用法
  2. spring的AOP配置之@注解方式
  3. 浅谈AJAX并实现使用pagehelper-5.1.10.jar分页插件实现异步从数据库中获取数据分页显示
  4. Android 12来了,支持更多设备,你的应用准备好了么?
  5. 练手CF3-C - Wormhouse
  6. 获取ini内容 GetPrivateProfileString GetPrivateProfileInt
  7. ASP.NET Core Web 支付功能接入 微信-扫码支付篇
  8. tomcat 下catalina.out 日志乱码问题处理
  9. greenPlum资源隔离
  10. gulp前端构建化工具,帮你搞定不同浏览器的兼容性写法问题