Vue应用程序开发
上QQ阅读APP看书,第一时间看更新

1.3 Vue.js的响应式理解

Vue.js是一套响应式系统(Reactivity System)。许多前端框架(如Angular、React、Vue)都有自己的响应式引擎。对于Vue响应式,官方文档的解释是,当用户把一个普通的JavaScript对象传给Vue实例的data选项时,Vue.js将遍历此对象的所有属性,并使用Object.defineProperty把这些属性全部转换为getter/setter。简单来说,即在修改data属性之后,Vue.js会立刻监听,立刻渲染并更新页面。下面通过一个实例来具体理解Vue.js的响应式,代码如下。


<div id="app">
        <div>Price :¥{{ price }}</div> 
        <div>Total:¥{{ price * quantiy }}</div> 
        <div>Taxes: ¥{{ totalPriceWithTax }}</div> 
        <button @click="changePrice">改变价格</button> 
</div> 
 <script type="text/javascript"> 
      var app = new Vue({ 
      el: '#app', 
      data() { 
         return { 
         price: 5.0, 
         quantiy: 2 
      }; 
  }, 
  computed: { 
    totalPriceWithTax() { 
      return this.price * this.quantity * 1.03; 
    } 
  }, 
  methods: { 
    changePrice() { 
      this.price = 10; 
    } 
  } 
}) 
</script> 

价格改变前后的浏览器页面渲染效果如图1-5和图1-6所示。

在以上实例中,当数据price发生变化的时候,Vue.js就会自动做3件事情:更新页面中price的值;计算表达式price*quantity的值,更新页面;调用totalPriceWithTax函数,更新页面。数据发生变化后,会重新对页面进行渲染,这就是Vue响应式。那么,这一切是怎么做到的呢?想完成这个过程,就需要侦测数据的变化,在收集视图依赖于哪些数据和数据变化时,自动“通知”需要更新的视图部分并进行更新,即所谓的数据劫持/数据代理、依赖收集和发布订阅模式。其中,最核心的方法便是通过Object.defineProperty()来实现对属性的监听,达到监听数据变动的目的。要实现MVVM的数据双向绑定,就必须实现以下几点。

图1-5 价格改变前的浏览器页面渲染效果

图1-6 价格改变后的浏览器页面渲染效果

(1)实现一个数据监听器(Observer),能够对数据对象的所有属性进行监听,如有变动可取得最新值并通知订阅者。

(2)实现一个指令解析器(Compile),对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数。

(3)实现一个订阅者(Watcher),作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图。Vue响应式实现原理如图1-7所示。

图1-7 Vue响应式实现原理