官方文档:
    当你把一个普通的JavaScript对象传入Vue实例作为data选项,Vue将遍历此对象所有的属性,并使用Object.defineProperty把这些属性全部转为getter/setter。这些getter/setter对用户来说是不可见的,但是内部它们让Vue能够追踪依赖,在属性被访问和修改时通知变更。

    所以Vue2.x的数据响应式是通过 Object.defineProperty数据进行劫持,同时结合观察者模式
    Object.defineProperty 示例

    1. <!-- Vue2.x 数据响应式原理 -->
    2. <!DOCTYPE html>
    3. <html lang="en">
    4. <head>
    5. <meta charset="UTF-8">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>数据响应式</title>
    8. </head>
    9. <body>
    10. <div id="app">
    11. Hello Vue
    12. </div>
    13. <script>
    14. // 模拟Vue实例 data 数据
    15. let data = {
    16. msg: '响应式数据',
    17. count: 0
    18. }
    19. // 模拟Vue实例
    20. let vm = {};
    21. function defineProperty (data) {
    22. //data对象枚举自身属性,并返回数组
    23. Object.keys(data).forEach(key => {
    24. Object.defineProperty(vm,key,{
    25. // 可枚举(可以遍历)
    26. enumerable: true,
    27. // 可配置(可以使用delete 删除, 可以使用)
    28. configurable: true,
    29. // 获取值执行
    30. get() {
    31. console.log('getter:', data[key])
    32. return data[key]
    33. },
    34. // 更新值时执行
    35. set(newValue) {
    36. console.log('setter:', data[key])
    37. if(data[key] === newValue) {
    38. return ;
    39. }
    40. data[key] = newValue
    41. document.querySelector("#app").textContent=newValue;
    42. }
    43. })
    44. })
    45. }
    46. //将data 传入自定义函数中,将每一条属性赋予响应式
    47. defineProperty(data)
    48. vm.msg = 'Hello响应式'
    49. console.log(vm.msg);
    50. </script>
    51. </body>
    52. </html>