谈谈因Vue.js引发关于getter和setter的思考

 更新时间:2016年12月02日 09:04:31   投稿:daisy  
最近因为公司的新项目决定使用Vue.js来做,但在使用的过程中发现了一个有趣的事情,因为发现的这个事情展开了一些对于getter和setter的思考,具体是什么下面通过这篇文章来一起看看吧,有需要的朋友们可以参考学习。

起因

当我打印出Vue实例下的data对象里的属性时,发现了一个有趣的事情:

它的每个属性都有两个相对应的getset方法,我觉的这是多此一举的,于是去网上查了查Vue双向绑定的实现原理,才发现它和Angular.js双向绑定的实现原理完全不同,Angular是用的数据脏检测,当Model发生变化,会检测所有视图是否绑定了相关数据,再更改视图。而Vue使用的发布订阅模式,是点对点的绑定数据。

Vue的数据绑定只有两个步骤,compile=>link

我一直在想,vue是通过什么去监听用户对Model的修改,直到我发现Vue的data里,每个属性都有setget属性,我才明白过来。

在平时,我们创建一个对象,并修改它的属性,是这样的:

 var obj = {
  val:99
 }
 obj.val = 100;
 console.log(obj.val)//100

没有任何问题,但是如果要你去监测,当我修改了这个对象的属性时,要去做一些事,你会怎么做?

相关思考

这就要用到gettersetter了。

假设我现在要给一个码农对象添加一个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对象,打印出来的效果是一样的,都拥有getset属性。

我们来一步步分析下上面的代码,很有趣。

我们先创建一个对象字面量:

var Coder = function() {...}

再把this缓存一下:

var that = this;

接下来是最重要的,我们return了一个对象回去:

{

  get name(){...},

  set name(val){...}

}

顾名思义,get为取值,set为赋值,正常情况下,我们取值和赋值是用obj.prop的方式,但是这样做有一个问题,我如何知道对象的值改变了?所以就轮到set登场了。

你可以把getset理解为function,当然,只是可以这么理解,这是完全不一样的两个东西。

接下来创建一个码农的实例,isMe;此时,isMe是没有name属性的,当我们调用isMe.name时,我们会进入到get name(){...}中,先判断isMe是否有name属性,答案是否定的,那麽就添加一个name属性,并给它赋值:"你还没有取名";如果有name属性,那就返回name属性。

看到这里你一定知道get怎么使用了,对,你可以把get看成一个取值的函数,函数的返回值就是它拿到的值。

我感觉比较重要的是set属性,当我给实例赋值:

isMe.name="周神"

此时,会进入set name(val){...};形参val就是我赋给name属性的值,在这个函数里,我就可以做很多事了,比如双向绑定!因为这个值的每次改变都必须经过set,其他方式是改变不了它的,相当于一个万能的监听器。

还有另一种方法可以实现这个功能。

ES5的对象原型有两个新的属性__defineGetter____defineSetter__ ,专门用来给对象绑定get和set。

可以这样书写:

 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)

效果是一样的,建议使用下面这种方式,因为是在原型上书写,所以可以继承和重用。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

相关文章

  • 学习笔记之Vuex的用法总结(Vue状态管理)

    学习笔记之Vuex的用法总结(Vue状态管理)

    这篇文章主要介绍了学习笔记之Vuex的用法总结(Vue状态管理),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • vue element封装form表单的实现

    vue element封装form表单的实现

    本文主要介绍了vue element封装form表单的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 关于Element上传组件beforeUpload上传前限制失效问题

    关于Element上传组件beforeUpload上传前限制失效问题

    这篇文章主要介绍了Element上传组件beforeUpload上传前限制失效问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 如何使用Webstorm和Chrome来调试Vue项目

    如何使用Webstorm和Chrome来调试Vue项目

    这篇文章主要介绍了如何使用Webstorm和Chrome来调试Vue项目,对Vue感兴趣的同学,一定要看一下
    2021-05-05
  • Vue 报错-4058 ENOENT:no such file or directory的原因及解决方法

    Vue 报错-4058 ENOENT:no such file or directory的原因及解决方法

    Vue 报错-4058 ENOENT: no such file or directory的原因和解决办法,关于为什么为会报这个错误,按照字面意思的理解就是没有找到这个文件或这个路径,说明是路径不对,本文给大家分享解决方案,感兴趣的朋友一起看看吧
    2023-10-10
  • vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip

    vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip

    这篇文章主要介绍了vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • vuex页面刷新导致数据丢失的解决方案

    vuex页面刷新导致数据丢失的解决方案

    这篇文章主要介绍了vuex页面刷新导致数据丢失的解决方案,帮助大家更好的使用vue框架,感兴趣的朋友可以了解下
    2020-12-12
  • vue diff算法全解析

    vue diff算法全解析

    这篇文章主要介绍了vue diff算法的使用,帮助大家更好的理解和学习使用vue,感兴趣的朋友可以了解下
    2021-04-04
  • vue实现上传图片添加水印(升级版)

    vue实现上传图片添加水印(升级版)

    这篇文章主要为大家详细介绍了vue实现上传图片添加水印的升级版,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Vue 中 createElement 使用实例详解

    Vue 中 createElement 使用实例详解

    Vue 提供了createElement 来创建虚拟dom,方便我们来函数化的方式来定义复杂的组件结构,这篇文章主要介绍了Vue 中 createElement 使用详解,需要的朋友可以参考下
    2022-10-10

最新评论