vue2_5、MVVM模型、数据代理
1、MWM模型
mvvm模型:就是把数据和dom通过一个中间对象进行连接。

-
M:模型Model, data中的数据,把它当作一个单独的模块,不属于VM,因为VM对象里会将它复制一份在里面作为数据代理。data里的数据改变vue会重新解析模板。
-
V:视图View,模板代码
-
VM:视图模型ViewModel, Vue实例
观察发现
data中所有的属性,最后都出现在了vm身上vm身上所有的属性及Vue原型身上所有的属性,在Vue模板中都可以直接使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>初始vue</title>
<!-- 引入vue-->
<script src="/vueBaseJs/vue.js"></script>
</head>
<body>
<div id="root">
<h1>学校名:{{name}}</h1>
<h1>学校地址:{{address}}</h1>
<h1>{{$options}}</h1>
</div>
<script>
Vue.config.productionTip=false;//阻止vue启动时生成生产提示
const vm=new Vue({
el:"#root",
data:function(){
return {
name:"李四",
address:"南充"
}
}
});
console.log(vm);
</script>
</body>
</html>
数据交换:

或者这样

大概流程:dom加载后执行js,然后vue就去获取容器里的dom,将里面的用vue写法的内容给替换为对应的数据(向model拿),然后再把修改后的dom返回给容器。不然浏览器会把{{name}}原格式输出。正因为有了vue的一番操作,将{{name}}替换为对应的数据。

2、数据代理
数据代理:通过一个对象代理对另一个对象中属性的操作(读写)。
如:
const obj1={x:100};
const obj2={y:200};
//让obj2成为obj1的数据代理(也就是让obj2能访问和操作obj1的属性)
Object.defineProperty(obj2,"x",{
get:function(){
return obj1.x;
},
set:function(value){
obj1.x=value;
}
});
//这样在读obj2的x属性就等于是在间接操作obj1的x属性。
在控制台输出obj2对象可以看到,当鼠标悬停在obj2的x属性上时,就会有一个getter标识,就代表这个x属性是会调用get函数来读取值。

obj2的x属性在逻辑上就如下图一下连接着obj1的x属性。

vue中的数据代理
-
Vue中的数据代理通过Vue的实例vm对象来代理data对象中属性的操作(读/写)。
-
Vue中数据代理的好处:更加方便的操作data中的数据。
-
基本原理:
a.通过object.defineProperty()把data对象中所有属性添加到vm上
b.为每一个添加到vm上的属性,都指定一个getter和setter
c.在getter和setter内部去操作(读/写)data中对应的属性。

Vue将data中的数据拷贝了一份到_data属性中,又将_data里面的属性提到Vue实例中(如name) ,通过defineProperty实现数据代理,这样通过geter/setter操作name,进而操作_data中的name。而_data又对data进行数据劫持,实现响应式。一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新。也就是改变_data里的数据,模型data也会受影响,而data数据改变,就会影响到页面上的值,因为vue会监听data模块。
vue的实例vm身上的_data是实例化时代码里的data的关系:就是实例身上的_data是data的数据代理,改实例身上的_data实际上是间接改data的属性。data就是MVVM里的Model,它在逻辑上是不属于vue的实例vm的。而是单独存在的。实例vm身上根本不可能有data属性,在实例化vue的实例vm的时候传进去的配置对象里的data在逻辑上本身就是单独的一个模块。实例vm确实会拷贝一个data存在自己身上,只不过这个属性名叫_data。
实际上,vue的实例vm身上的_data通过vue底层实现了更改_data里的数据data里也会跟着改变,这就是上面说的它们存在着某种类似数据代理的关系。实际上,vue也为了方便我们开发,把_data里的属性给添加到了vm实例身上,这也是通过数据代理实现的,只是为了我们开发,比如:页面里可以用name直接访问到_data里的name,实际上也可以通过_data.name访问,但是这样比较麻烦,所以vue才做了_data的数据代理。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>初始vue</title>
<!-- 引入vue-->
<script src="/vueBaseJs/vue.js"></script>
</head>
<body>
<div id="root">
<h1>学校名称:{{name}}</h1><br/>
<h1>地址:{{address}}</h1>
</div>
<script>
Vue.config.productionTip=false;//阻止vue启动时生成生产提示
const obj={
name:"南职",
address:"南充"
};
const vm=new Vue({
el:"#root",
data:function(){
return obj;
}
});
</script>
</body>
</html>

浙公网安备 33010602011771号