zoukankan      html  css  js  c++  java
  • vue.js中的虚拟DOM

    typora-copy-images-to: assets

    虚拟DOM介绍

    1. 什么是虚拟DOM
      虚拟DOM是将状态映射成试图的众多解决方案之一。页面交互的本质还是通过改变状态(变量)来改变试图渲染,而框架(像主流框架vue、react、angular)的应用可以让我们把关注的焦点更多的放在状态上,省略对DOM的操作(框架内部已经帮我们完成了)。
      而虚拟DOM映射视图的方式是通过状态生成一个虚拟节点树,然后通过虚拟节点树进行渲染。虚拟节点树本质上是一个普通的js对象,它包含了创建一个DOM元素所需要的属性

    2. 为什么要在vue中引入虚拟DOM

      • 像react(虚拟DOM)、angular(脏检查)对状态变化的侦测都有一个特点:他们不知道那个状态发生了变化,当有状态发生变化时,就对整个视图进行重新渲染。
        // 问题:react angular vue的监听原理对比
        // 1. 脏检查、虚拟DOM、细粒度绑定分别是什么原理
        // 1.1 脏检查:页面所有的数据变动都是由事件或者异步操作触发的。
        // 浏览器提供了监测事件的API,但没有检测数据变化的API。
        // 因此每次在执行一次事件后都会对数据进行大检查,监听那些数据发生了改变。
        // 网址:https://www.zhihu.com/question/43470158/answer/108283135
        // 1.2 虚拟DOM:生成一个类DOM对象,通过这个对象可以生成DOM元素。
        // react是怎么来监听数据变化的呢?
        // 只要页面有事件发生,就会把所有的DOM全部删除,再重新渲染。不会进行DOM对比
        // 1.3 细粒度绑定
        // 基本原理在第二和第三章有讲解
      • 在vue1.0中用的细粒度监听方式,但每一个监听都会对应一个watcher,这样对内存和依赖(请看前面两篇博客)追踪的开销太大。vue2.0中采用中等粒度 + 虚拟DOM的解决方案。既以组件级别为一个依赖实例,组件内部状态的变化监听就由虚拟DOM完成。
    3. vue中的虚拟DOM
      执行渲染函数会生成虚拟树节点,在虚拟DOM渲染视图的过程中,会将新生成的vnode与上一次渲染的vnode进行对比,找出真正需要更新的节点。而这个对比的过程成为patch算法,也是虚拟DOM的核心,后面的博客会讲解到

    4. vnode
      vuejs中有一个Vnode类,通过它可以实例化不同类型的vnode实例,不同类型的vnode实例代表不同类型的DOM元素。DOM元素有元素节点、文本节点、注释节点等,对应的vnode也有不同类型。vnode本质上是js中的一个对象,可以把它理解为节点描述对象
      export default class VNode {
      tag: string | void;
      data: VNodeData | void;
      children: ?Array;
      text: string | void;
      elm: Node | void;
      ns: string | void;
      context: Component | void; // rendered in this component's scope
      key: string | number | void;
      componentOptions: VNodeComponentOptions | void;
      componentInstance: Component | void; // component instance
      parent: VNode | void; // component placeholder node

        // strictly internal
        raw: boolean; // contains raw HTML? (server only)
        isStatic: boolean; // hoisted static node
        isRootInsert: boolean; // necessary for enter transition check
        isComment: boolean; // empty comment placeholder?
        isCloned: boolean; // is a cloned node?
        isOnce: boolean; // is a v-once node?
        asyncFactory: Function | void; // async component factory function
        asyncMeta: Object | void;
        isAsyncPlaceholder: boolean;
        ssrContext: Object | void;
        fnContext: Component | void; // real context vm for functional nodes
        fnOptions: ?ComponentOptions; // for SSR caching
        fnScopeId: ?string; // functional scope id support
       
        constructor (
          tag?: string,
          data?: VNodeData,
          children?: ?Array<VNode>,
          text?: string,
          elm?: Node,
          context?: Component,
          componentOptions?: VNodeComponentOptions,
          asyncFactory?: Function
        ) {
          this.tag = tag
          this.data = data
          this.children = children
          this.text = text
          this.elm = elm
          this.ns = undefined
          this.context = context
          this.fnContext = undefined
          this.fnOptions = undefined
          this.fnScopeId = undefined
          this.key = data && data.key
          this.componentOptions = componentOptions
          this.componentInstance = undefined
          this.parent = undefined
          this.raw = false
          this.isStatic = false
          this.isRootInsert = true
          this.isComment = false
          this.isCloned = false
          this.isOnce = false
          this.asyncFactory = asyncFactory
          this.asyncMeta = undefined
          this.isAsyncPlaceholder = false
        }
       
        // DEPRECATED: alias for componentInstance for backwards compat.
        /* istanbul ignore next */
        get child (): Component | void {
          return this.componentInstance
        }
      }
      
      • vnode节点分类
        不同类型的节点之间,只是有效属性不同;比如注释节点有效属性只有text和i你Comment;其余属性默认都是undefiend或者false; 文本节点的有效属性只有text
        1. 注释节点:对应视图中的注释
          export const createEmptyVnode = text => {
          const node = new VNode()
          node.text = text
          node.isComment = true
          return node
          }
          对应的注释节点就是:
          {
          text: '注释节点',
          isComment: true
          }

        2. 文本节点: 对应视图中的文字,比如我是文本节点中的我是文本节点就是文本节点
          export const createTextVnode = text => {
          return new VNode(undefined, undefined, undefined, string(text))
          }
          对应的文本节点就是:
          {
          text: '这是文本节点'
          }

        3. 克隆节点: 将现有节点的属性复制到新节点当中;作用是优化静态节点和插槽节点;以静态节点为例,静态节点从第一次渲染后,无论页面中的状态怎么发生变化他都不会改变,因此只需第一次渲染的时候获取一下(在模板编译的优化器阶段就已经标注那些节点是静态节点,请看下篇博客)
          本人有个小问题:渲染静态节点的过程难道比优化器的实现过程更加耗费性能吗?

        4. 元素节点:
          常见的属性:

          • tag: 节点名称,对应着DOM元素标签名
          • tata: 包含了一些节点上的数据,如class、style attrs等(具体获取方式请看下篇博客)
          • children: 子节点
          • context: 当前组件的vue实例
  • 相关阅读:
    算法题汇集
    C# WinForm MDI左右分栏 多文档
    DDoS和CC攻击的区别
    搭建java程序写的博客Jpress
    U盘图标DIY方法
    磁盘空间不够用?教你一键清理电脑重复文件Duplicate File Finder
    给WordPress文章页URL赋予.html后缀
    使用七牛云和PicGo搭建图床
    wordpress好用的Markdown插件WP Editor.MD
    虚拟主机、VPS、云服务器三者的区别
  • 原文地址:https://www.cnblogs.com/tina-12138/p/13173826.html
Copyright © 2011-2022 走看看