1. 真实DOM: 文档对象模型, 是网页中标签在js中的映射对象, 每一个标签都是一个dom元素对象<br /> 虚拟DOM: 通过js对象结构模拟html标签结构的一种数据格式, 他并不是标签元素, 只不过结构和标签元素结构相似而已, 虚拟dom只针对数据对象操作, 与界面视图无关, 故,虚拟dom执行效率比真实dom执行效率高很多
    1. <body>
    2. <script src='https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js'></script>
    3. <div id='myApp'>
    4. vue2.0开始, vue中引入了虚拟dom的概念(抄react), 虚拟dom实质上是使用js对象代替了dom元素结构, 数据更新是遍历dom替换成了遍历js对象, 大大提高了遍历执行的速度和效率, 使页面渲染更新更加高效, 节省内存和性能
    5. <button @click="btnClick">更新</button>
    6. <h1 id="title">{{name}}</h1>
    7. <div id="d1">
    8. <span class="more">更多内容</span>
    9. </div>
    10. </div>
    11. <script>
    12. new Vue({
    13. el: '#myApp',
    14. data: {
    15. name: "张三"
    16. },
    17. methods: {
    18. btnClick(){
    19. // this.name = "李四" // 正常的数据更新
    20. // 虚拟DOM实现步骤3: data数据更新时, 会调用数据底层的set函数
    21. this.nameSet("李四")
    22. },
    23. // 模拟实现name字段的set函数
    24. nameSet(name){
    25. this.name = name
    26. // 虚拟DOM实现步骤4: 在data数据更新之后, 创建一个新的虚拟dom树
    27. this.virtualDOM2 = {
    28. name: "div",
    29. attr: [
    30. {id: "myApp"}
    31. ],
    32. children: [
    33. {
    34. name: "button",
    35. events: [
    36. {click: this.btnClick}
    37. ],
    38. children: "更新"
    39. },
    40. {
    41. name: "h1",
    42. attr: [
    43. {id: 'title'}
    44. ],
    45. children: this.name
    46. },
    47. {
    48. name: "div",
    49. attr: [
    50. {id: 'd1'}
    51. ],
    52. children: [
    53. {
    54. name: "span",
    55. attr: [
    56. {class: "more"}
    57. ],
    58. children: "更多内容"
    59. }
    60. ]
    61. }
    62. ]
    63. }
    64. console.log(this.virtualDOM1, this.virtualDOM2)
    65. // 虚拟DOM实现步骤5:拿新的虚拟dom对象和原来的虚拟dom对象做对比, 找出他们之间的最小差异, 把新老虚拟dom树传入一个diff函数内,计算差异, diff函数中有算法(叫diff算法)用于计算dom树差异,也是虚拟dom中的核心算法
    66. // var diffArr = Vue.diff(this.virtualDOM1, this.virtualDOM2) 模拟diff算法的调用
    67. var difArr = [
    68. {
    69. query: "#title",
    70. value: '李四'
    71. }
    72. ]
    73. // 虚拟DOM实现步骤5: 遍历最小差异数组, 执行真实dom操作, 针对性的更新数组中涉及到的标签元素, 实现局部刷新
    74. difArr.forEach(item=>{
    75. document.querySelector(item.query).innerText = item.value
    76. })
    77. }
    78. },
    79. created() {
    80. // 虚拟DOM实现步骤1: 在vue对象初始化时, 把vue模板中dom标签结构转换成虚拟dom对象结构
    81. this.virtualDOM1 = {
    82. name: "div",
    83. attr: [
    84. {id: "myApp"}
    85. ],
    86. children: [
    87. {
    88. name: "button",
    89. events: [
    90. {click: this.btnClick}
    91. ],
    92. children: "更新"
    93. },
    94. {
    95. name: "h1",
    96. attr: [
    97. {id: 'title'}
    98. ],
    99. children: this.name
    100. },
    101. {
    102. name: "div",
    103. attr: [
    104. {id: 'd1'}
    105. ],
    106. children: [
    107. {
    108. name: "span",
    109. attr: [
    110. {class: "more"}
    111. ],
    112. children: "更多内容"
    113. }
    114. ]
    115. }
    116. ]
    117. }
    118. },
    119. beforeMount() {
    120. // 虚拟DOM实现步骤2: 使用虚拟dom对应的找到动态数据所在的标签把动态数据渲染到视图上
    121. document.getElementById("title").innerText.replace("{{name}}", this.name)
    122. },
    123. })
    124. </script>
    125. </body>