这里有新鲜出炉的 vue.js 教程,程序狗速度看过来!
Vue.js 是构建 web 界面的 JavaScript 库,提供数据驱动的组件,还有简单灵活的 API,使得 MVVM 更简单。
最近因为公司的新项目决定使用 Vue.js 来做,但在使用的过程中发现了一个有趣的事情,因为发现的这个事情展开了一些对于 getter 和 setter 的思考,具体是什么下面通过这篇文章来一起看看吧,有需要的朋友们可以参考学习。
起因
当我打印出 Vue 实例下的 data 对象里的属性时,发现了一个有趣的事情:
它的每个属性都有两个相对应的
和
- get
方法,我觉的这是多此一举的,于是去网上查了查 Vue 双向绑定的实现原理,才发现它和 Angular.js 双向绑定的实现原理完全不同,Angular 是用的数据脏检测,当 Model 发生变化,会检测所有视图是否绑定了相关数据,再更改视图。而 Vue 使用的发布订阅模式,是点对点的绑定数据。
- set
Vue 的数据绑定只有两个步骤,
。
- compile=>link
我一直在想,vue 是通过什么去监听用户对 Model 的修改,直到我发现 Vue 的 data 里,每个属性都有
和
- set
属性,我才明白过来。
- get
在平时,我们创建一个对象,并修改它的属性,是这样的:
- var obj = {
- val: 99
- }
- obj.val = 100;
- console.log(obj.val) //100
没有任何问题,但是如果要你去监测,当我修改了这个对象的属性时,要去做一些事,你会怎么做?
相关思考
这就要用到
和
- getter
了。
- setter
假设我现在要给一个码农对象添加一个
属性,而且每次更新
- name
属性时,我要去完成一些事,我们可以这样做:
- name
- var Coder = function() {
- var that = this;
- return {
- get name() {
- if (that.name) {
- return that.name
- }
- return '你还没有取名'
- },
- set name(val) {
- console.log('你把名字修成了' + val) that.name = val
- }
- }
- }
- var isMe = new Coder() console.log(isMe.name) isMe.name = '周神'console.log(isMe.name) console.log(isMe)
输出:
你会发现这个对象和最上面的 Vue 中的
对象,打印出来的效果是一样的,都拥有
- data
和
- get
属性。
- set
我们来一步步分析下上面的代码, 很有趣。
我们先创建一个对象字面量:
- var Coder = function() {...
- }
再把
缓存一下:
- this
- var that = this;
接下来是最重要的,我们
了一个对象回去:
- return
- {
- get name() {...
- },
- set name(val) {...
- }
- }
顾名思义,get 为取值,set 为赋值,正常情况下,我们取值和赋值是用
的方式,但是这样做有一个问题,我如何知道对象的值改变了?所以就轮到 set 登场了。
- obj.prop
你可以把
和
- get
理解为
- set
,当然,只是可以这么理解,这是完全不一样的两个东西。
- function
接下来创建一个码农的实例,isMe;此时,isMe 是没有
属性的,当我们调用
- name
时,我们会进入到
- isMe.name
中,先判断 isMe 是否有
- get name(){...}
属性,答案是否定的,那麽就添加一个
- name
属性,并给它赋值:"你还没有取名";如果有
- name
属性,那就返回
- name
属性。
- name
看到这里你一定知道
怎么使用了,对,你可以把
- get
看成一个取值的函数,函数的返回值就是它拿到的值。
- get
我感觉比较重要的是
属性,当我给实例赋值:
- set
- isMe.name = "周神"
此时,会进入
形参 val 就是我赋给
- set name(val){...};
属性的值,在这个函数里,我就可以做很多事了,比如双向绑定!因为这个值的每次改变都必须经过 set,其他方式是改变不了它的,相当于一个万能的监听器。
- name
还有另一种方法可以实现这个功能。
ES5 的对象原型有两个新的属性
和
- __defineGetter__
,专门用来给对象绑定 get 和 set。
- __defineSetter__
可以这样书写:
- var Coder = function() {}
- Coder.prototype.__defineGetter__('name',
- function() {
- if (this.name) {
- return this.name
- } else {
- return '你还没有取名'
- }
- }) Coder.prototype.__defineSetter__('name',
- function(val) {
- this.name = val
- }) var isMe = new Coder() console.log(isMe.name) isMe.name = '周神'console.log(isMe.name) console.log(isMe)
效果是一样的,建议使用下面这种方式,因为是在原型上书写,所以可以继承和重用。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
来源: http://www.phperz.com/article/17/0704/329979.html