虚拟dom和diff算法-1(h,patch)

303 阅读3分钟

来源于Vue源码解析系列课程_哔哩哔哩_bilibili,侵删

课程简介

image.png

最笨的方法

image.png

diff算法(最小量更新算法)different

image.png

例子:

image.png

虚拟dom

image.png 左边是真实dom,右边是js对象 面试官可能会问diff算法优化的策略,更新字节点的策略

snabbdom简介,虚拟dom
snabbdom的h函数是如何工作的
diff算法原理
手写diff算法

image.png

image.png

正式学习

1.snabbdom简介和测试环境搭建

image.png github.com/snabbdom/sn…

image.png 看ts,用js

image.png 首先看看文档结构:

image.png

    配置环境
    1.npm i -S snabbdom
    2.npm -D webpack@5 webpack-clik@3 webpack-dev-server@3
    3.webpack.config.js:
    // 从https://www.webpackjs.com/去配置


        const path = require('path');

       


            module.exports = {

            entry: './src/index.js',//入口

            output: {//出口

            publicPath: 'xuni',//虚拟打包路径,文件夹不会真正的生成,而是在8080端口虚拟生成

            filename: 'bundle.js'//打包出来的文件名,不会真正的物理生成

            },

            devServer:{

            port:8080,//端口号

            contentBase:'www',//静态资源文件夹

            }

        };
    package.json:
    "scripts": {

"test": "echo \"Error: no test specified\" && exit 1",

"dev":"webpack-dev-server"

}


index.js的内容来自于GitHub上官方给的example:

image.png 需要注意的是,想要正确运行起来需要更改以下几点:

 1.index.html中要注意idid名必须保持这个,因为再index.js18行:const container = document.getElementById("container")

image.png 2.index.js20行函数改成随意的匿名函数,30行同理 最后的运行:npm run dev

ps.其实这个配置方法和前面的mustache.js配置方法完全一样的~

虚拟dom和h函数

image.png sel:选择器

image.png diff算法是新的虚拟dom和老的虚拟dom进行diff,精细化比较
发现有新的dom,再对真实dom进行createElement()和appendChild()或者insertBefore()等等操作
暂时不研究dom怎么变成虚拟dom的(属于模板编译的原理范畴,暂不研究,和之前的mustache.js原理有一点点相似)

image.png

h函数用来产生虚拟节点(vnode)

image.png

image.png

children:子元素(没有子元素)
data:属性,样式
elm:这个虚拟dom对应的真实dom,undefined表示这个dom还没有上树
key:唯一标识
sel:选择器
text:文字 

练习:

image.png 在引入包的前提下,去进行实际操作
h(标签名,[属性],内容)

image.png 需要注意的是,h函数并不是真实产生真的dom,是虚拟节点,另外,这里的props是一个对象,你可以任意增加自己想要的各种属性

image.png 那怎么让虚拟节点显示在页面中呢?使用patch函数(是diff算法的核心) const patch = init([classModule,propsModule,styleModule,eventListenersModule]) (注意写法!这四个参数都来自于引入的包:类名、props、样式、事件监听模块), 最后再让虚拟节点上树:

image.png 页面中就有百度超链接了,并且可以点击跳转

到目前为止的小总结:
   1.使用h函数创建虚拟节点,为啥要创建虚拟dom?因为diff算法是发生在虚拟dom上的(其实v-for的底层逻辑都是会被变成h函数)
   2.使用patch函数使得虚拟节点上树
   3.要注意的是,patch函数一个容器只能使一个虚拟节点上树,所以一个页面中只能由一个patch(虚拟节点可以嵌套,但是还没开始学习)

image.png

嵌套就来啦

image.png 再次:h(标签名,[属性],内容)

image.png 都可以进行嵌套,vnode被children属性嵌套起来
如果只有一个子元素,数组可以省略,但是超过一个,就必须要有数组

尚硅谷yyds!