欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

Vue.js中的MVVM

发布时间:2024/4/14 109 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Vue.js中的MVVM 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

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> 复制代码 超强干货来袭 云风专访:近40年码龄,通宵达旦的技术人生

总结

以上是生活随笔为你收集整理的Vue.js中的MVVM的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。