十三、MVVM模式
MVVM是Model-View-ViewModel的缩写
Model:代表数据模型也可以在model中定义数据修改和操作的业务逻辑,也可以称为数据层,因为它仅仅只关心数据,不关心任何行为
View:用户操作界面,当ViewModel对Mdodel进行更新的时候,会通过数据绑定更新到View
ViewModel:业务逻辑层,View需要什么数据,ViewModel要提供这个数据;View有某些操作ViewModel就要响应这些操作,所以可以说他是Model for View
mvvm即Model-View-ViewModel,mvvm的设计原理是基于mvc的,所以说mvvm不算是一种创新,充其量是一种改造,这其中的ViewModel便是一个小小的创新
1、Vue响应式数据原理解析
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
/*
如何去实现数据与视图绑定
1.需要知道哪个数据改变了。一般我们可以使用数据访问对象的方法,在vue中我们使用的是es5的对象访问属性get/set
2.需要知道修改的这个数据跟哪个视图有关联,观察者模式
3.修改视图
*/
// var test = {
// _a: undefined,
// get a() {
// return this._a
// },
// set a(newVal) {
// this._a = newVal
// }
// }
// console.log(test.a); // undefined
// test.a = 'abc';
// console.log(test.a); // abc
// console.log(test); // {_a: abc}
// // 如果不想打印出_a
// var test2 = (function () {
// var _a = undefined
// var test = {
// get a () {
// return _a;
// },
// set a (newVal) {
// _a = newVal;
// }
// }
// return test
// })
// console.log(test2); // {a: undefined}
// var test3 = {_a: 111};
// Object.defineProperty(test3, 'a', {
// get: function () {
// return this._a;
// },
// set: function (newVal) {
// this._a = newVal
// }
// })
// console.log(test3.a); // 111
// test3.a = 'abc'
// console.log(test3.a); // abc
// ----------------
// var data = {
// a: 1
// };
// var dep = []; // 依赖收集, 消息中心
// var target = null; // 订阅者或者叫观察者
// Object.defineProperty(data, 'a', {
// get: function () {
// dep.push(target)
// },
// set: function (newVal) {
// for(var i = 0; i < dep.length; i++) {
// dep[i]()
// }
// }
// })
// function watch(exp, fn) {
// target = fn;
// data[exp] // 调用 data[exp].get()
// }
// watch('a', function () {
// console.log('我是第一个监听a改变的函数');
// })
// watch('a', function () {
// console.log('我是第二个监听a改变的函数');
// })
// data.a = 2
/*
上面代码存在的几个问题:
1.我们现在访问不到a, 并且a的值需要另一个变量区暂存。
2.目前只做了一个数据的收集工作
3.如果再次访问属性的时候,就会重复收集依赖
*/
var data = {
a: 1,
b: 2
};
for(var key in data) {
(function (key) {
var dep = [];
var value = data[key];
Object.defineProperty(data, key, {
get: function () {
for(var i = 0; i < dep.length; i++) {
if (dep[i] === target) {
return value
}
}
dep.push(target)
return value
},
set: function (newVal) {
if (newVal !== value) {
value = newVal;
for (var i = 0; i < dep.length; i++) {
dep[i]()
}
}
}
})
})(key)
}
// var dep = []; // 依赖收集, 消息中心
var target = null; // 订阅者或者叫观察者
// Object.defineProperty(data, 'a', {
// get: function () {
// dep.push(target)
// },
// set: function (newVal) {
// for(var i = 0; i < dep.length; i++) {
// dep[i]()
// }
// }
// })
function render() {
document.write('<div>文案test: <p>a的值: ' + data.a + ', b的值:' + data.b + '</p></div>')
}
function watch(exp, fn) {
target = fn;
if (typeof exp === 'function') {
exp();
return;
}
data[exp] // 调用 data[exp].get()
}
// watch('a', function () {
// console.log('我是第一个监听a改变的函数');
// })
// watch('a', function () {
// console.log('我是第二个监听a改变的函数');
// })
// watch('b', function () {
// console.log('我是第一个监听b改变的函数');
// })
watch(render, render)
data.a = 2
data.b = 3
</script>
</head>
<body>
</body>
</html>本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。