963   HTML JS

一,前端开发过程,经常要通过JS操作DOM,获取视图View的数据更新到模型Model;或者将模型Model的数据,更新到视图View!

这种模式目前存在一些问题:

1、需要手动更新Model和View,当Model发生变化,需要手动更新到View,反之也如此,过程重复且繁琐,多变的数据状态也难维护。
2,DOM相同的API被随处调用,操作冗余,维护起来成本很高;而且大量的DOM操作使页面渲染性能降低,加载速度变慢,影响用户体验。

 

二,当前比较流行的解决方法是使用MVVM模式,M即时Model,V即是View,VM即是ViewModel;
MVVM模式主要通过ViewModel实现了视图View和模型Model的双向绑定,无论视图还是模型数据更变,ViewModel都会自动更新到另外一方,无需手动操作了;
看张图说话

329886-20160704145557296-1159836269

 

 

首先,我们将上图中的DOM Listeners和Data Bindings看作两个工具,它们是实现双向绑定的关键。
从View侧看,ViewModel中的DOM Listeners工具会帮我们监测页面上DOM元素的变化,如果有变化,则更改Model中的数据;
从Model侧看,当我们更新Model中的数据时,Data Bindings工具会帮我们更新页面中的DOM元素。

 

 

三,这只是解决了上面的第一个问题,至于第二个问题,则利用虚拟DOM的来优化;
真实DOM一般是直接写在HTML页面中的节点,或者通过innerHTML方式填充的节点;虚拟DOM则是通过JS中的dom对象渲染出来的html节点,这些节点保存在js运行的缓存当中,并不是真实存在,所以称为virtual dom

有实例好理解

 

真实DOM

 

 <html>
     <body>
         <div id="app">
             <p id="real-dom" >我是真实DOM</p>
         </div>
     </body>
</html>

 

 

虚拟DOM

 

 <html>
      <body>
         <div id="app">
         <!-- 虚拟DOM将会在这里创建 -->
         </div>

     <script src="vue.js"></script>
     <script>
         new Vue({
             el: '#app',
             render() {
                var node = this.$createElement;
                return node(
                           'p', 
                            { 
                                attrs: { id: 'virtual-dom' } 
                            }, 
                            '我是虚拟DOM'
                       );
                }
         });
    </script>

    </body>
</html>

 

最终虚拟DOM将会创建在app这个节点下,而且是JS对象的方式渲染出来的DOM,这有什么好处呢?
1,当操作真实DOM时需要通过getElementById方式,在成千上万个DOM中获取到节点,计算比较缓慢;通过 innerHTML 方式填充的节点会先把原有节点内容删除,然后再重建,在获取真实节点和更新内容时,代价都是昂贵的;

2,虚拟 DOM 的优势在于,DOM建立在JS对象上,保存在缓存中,当需要更新DOM时,可先采用 diff 的方式对比前后DOM对象,然后做出最优化的更新选择,不一定要将整个节点删除再重建,这种方式性能更优上面的方式;




Leave a Reply

Your email address will not be published. Required fields are marked *