vuesetdata的简单介绍
本篇文章给大家谈谈vuesetdata,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、vue中数据双向绑定的原理是什么?
- 2、为什么Vue组件中的data是一个函数
- 3、为什么vue中data必须是一个函数
- 4、接口返回这样的数据,vue如何获取data中的数据?
- 5、vue生命周期和小程序生命周期
vue中数据双向绑定的原理是什么?
vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,其中比较关键的是数据劫持,下面咱们看一个例子。
var obj = {} Object.defineProperty(obj,'name',{ get:function(){ console.log("获取了"); }, set:function(){ console.log('修改了'); }})obj.name = 'fei';obj.name
Object.defineProperty( )是用来做什么的?它可以来控制一个对象属性的一些特有操作,比如读写权、是否可以枚举。
思路分析
实现mvvm主要包含两个方面,数据变化更新视图,视图变化更新数据:
三人行慕课
关键点在于data如何更新view,因为view更新data其实可以通过事件监听即可,比如input标签监听 'input' 事件就可以实现了。所以我们着重来分析下,当数据改裂绝变,如何更新视图的。
数据更新视图的重点是如何知道数据变了,只要知道数据变了,那么接下去的事都好处理。如何知道数据变了,其实上文我们已经给出答案了,就是通过Object.defineProperty(
)对属性设置一个set函数,当数据改变了就会来触发这个函数,所以我们只要将一些需要更新的方法放在这里面就可以实现data更新view了。
三人行慕课
思路有了,接下去就是实现过程了。
实现过程
我们已经知道实现数据的双向绑定,首先要对数据进行劫持监听,所以我们需要设置一个监听器Observer,用来监听所有属性。如果属性发上变化了,就需要告诉订阅者Watcher看是否需要更新。因为订阅者是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者,然后在监听拦配器Observer和订阅者Watcher之间进行统一管理的。接着,我们还需要有一个指令解析器Compile,对每个节点元素进行扫描和解析,将相关指令对应初始化成一个订阅者Watcher,并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执行对应的更新函数,从而更新视图。因此接下去我们执行以下3个步骤,实现数据的双向绑定:
1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,肆衡姿从而更新视图。
3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
流程图如下:
三人行慕课
function objServer(obj){ let keys = Object.keys(obj); keys.forEach((item)={ definedActive(obj,item,obj[item]) }) return obj; } function definedActive(obj,item,val){ Object.defineProperty(obj,item,{ get(){ console.log(`${item}获取了`) }, set(newVlaue){ val = newVlaue; console.log(`${item}修改了`) } })} let obj = objServer({ a:1, b:2}) obj.aobj.b obj.a = 2;obj.b = 3;
为什么Vue组件中的data是一个函数
在创建或注册模板的时候,传入一个data属性作为用来绑定的数据。但是在组件中,data必须是一个函数,而不能直接把一个对象赋值给它。
Vue.component('my-component', {
template: 'divOK/div',
data() {
return {} // 返回一个唯一的对象,不要和其他组件共用一个对象进行返回
},
})
你在前面看到,在new Vue()的时候,是可以给data直接赋值为一个对象的。这是怎么回事,为什么到了组件这里就不行了。
你要理解,上面这个操作是一个简易操作,实际上,它首先需要创建一个组件构造器,然后注册组件。注册组件的本质其实就是建立困带一个组件构造器的引用。使用组件才是真正创建一个组件实例。所以,注册组件其实并不产生新的组件类,但会产生一个可以用来实例化的新方式。
理解这点之后,再理解js的原型链:
var MyComponent = function() {}
MyComponent.prototype.data = {
a: 1,
b: 2,
}
// 上面是一个虚拟的组件构造器,真实的组件构造器方法很多
var component1 = 陪兄new MyComponent()
var component2 = new MyComponent()
// 上面实例化出来两个组件实例,也芦尺袭就是通过my-component调用,创建的两个实例
component1.data.a === component2.data.a // true
component1.data.b = 5
component2.data.b // 5
可以看到上面代码中最后三句,这就比较坑爹了,如果两个实例同时引用一个对象,那么当你修改其中一个属性的时候,另外一个实例也会跟着改。这怎么可以,两个实例应该有自己各自的域才对。所以,需要通过下面方法来进行处理:
var MyComponent = function() {
this.data = this.data()
}
MyComponent.prototype.data = function() {
return {
a: 1,
b: 2,
}
}
这样每一个实例的data属性都是独立的,不会相互影响了。所以,你现在知道为什么vue组件的data必须是函数了吧。这都是因为js本身的特性带来的,跟vue本身设计无关。其实vue不应该把这个方法名取为data(),应该叫setData或其他更容易立即的方法名。
[img]为什么vue中data必须是一个函数
类比引用数据类型
Object是引用数据类型,如果不用function 返回,每个组件的data 都悔轮是内存的同一个地址,一个数据改变了其他也改变了;
javascipt只有函数构成作用域(注意理解作用域,只有 函数的{} 构成作用域, 对象的{} 以及 if(){} 都不构成作用域),data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响
举个