上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

Vue源码学习之虚拟Dom与Diff算法(二)

[复制链接]
  • TA的每日心情
    开心
    2022-7-21 11:43
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    4

    主题

    9

    回帖

    20

    积分

    助理工程师

    积分
    20

    新人报道

    发表于 2022-7-20 11:11:18 | 显示全部楼层 | 阅读模式

    本帖最后由 饭饭欧尼酱 于 2022-7-20 11:13 编辑

    本帖最后由 饭饭欧尼酱 于 2022-7-20 11:12 编辑

    本帖最后由 饭饭欧尼酱 于 2022-7-20 11:11 编辑

    Snabbdom简介

    Snabbdom是一个注重简单性、模块化、强大特性和性能的虚拟DOM库。
    Vue源码借鉴了Snabbdom
    github地址:Snabbdom中文翻译文档
    大家如果想了解vue的虚拟DOM,首先当然就是要安装这个库了!

    安装Snabbdom

    npm i -S snabbdom
    安装完了我们看看结构
    image.png
    这里我们只看build目录和src目录
    展开看看!
    image.png
    可以看到src下面存放的都是ts文件,这里就是snabbdom的Ts源码
    再看看build目录下面放的什么文件
    展开看看!
    image.png
    这里就是便于我们学习的js源码了,那么有好奇的读者会问.d.ts是什么啊?
    .d.ts就是声明文件,用于保存ts文件中的具体类型。

    安装WebPack

    Snabbdom库是DOM库,当然不能在nodejs环境运行,所以我们需要搭建webpack
    和webpack-dev-server开发环境,好消息是不需要安装任何loader!

    这里需要注意,必须安装最新版webpack@5,不能安装webpack@4,这是因为
    webpack4没有读取身份证中exports的能为,建议大家使用这样的版本:
    cnpm i -D webpack@5 webpack-cli@3 webpack-dev-server@3
    这里你不仅可以用npm 也可以用cnpm还可以用yarn反正你想怎么装怎么装,怎么开心怎么来!
    大家如果安装的很慢,可以使用淘宝镜像!
    npm config set registry https://registry.npm.taobao.org
    npm install -g cnpm --registry=https://registry.npm.taobao.org
    yarn config set registry http://registry.npm.taobao.org

    配置WebPack

    首先创建webpack.config.js文件
    image.png
    从官网复制配置文件:webpack官网
    image.png
    直接CV左侧的配置文件即可,也可以直接CV我下面的代码

    const path = require('path');
    
    module.exports = {
        //入口
        entry: './src/index.js',
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'bundle.js'
        }
    };

    除此之外,我们还需要在src下面创建一个index.js作为他的入口文件
    image.png
    配置完入口还需要配置他的出口和端口

    const path = require('path');
    
    module.exports = {
        //入口
        entry: './src/index.js',
        output: {
            //出口 
            publicPath: xuni,
            //不会真正的物理生成的
            filename: 'bundle.js'
        },
        devServer: {
            //端口号
            port: 8080,
            //静态资源目录
            contentBase: 'www',
        }
    };

    这里的pbulicPath就是虚拟打包路径,也就是说文件夹不会真正的生成,而是在8080端口虚拟生成。
    除此之外还需要创建一个www静态资源目录
    image.png
    然后我们在www静态资源目录下面创建一个index.html
    image.png
    在浏览器输入http://localhost:8080/即可看到我们的打包成功了!
    image.png
    我们在www中的index.html引入我们虚拟路径下的src="/xuni/bundle.js"
    就可以在src下的index.js书写我们的代码啦!

    测试Snabbdom环境

    CV官网文档代码

    var snabbdom = require('snabbdom');
    var patch = snabbdom.init([ // Init patch function with chosen modules
        require('snabbdom/modules/class').default, // makes it easy to toggle classes
        require('snabbdom/modules/props').default, // for setting properties on DOM elements
        require('snabbdom/modules/style').default, // handles styling on elements with support for animations
        require('snabbdom/modules/eventlisteners').default, // attaches event listeners
    ]);
    var h = require('snabbdom/h').default; // helper function for creating vnodes
    
    var container = document.getElementById('container');
    
    var vnode = h('div#container.two.classes', {on: {click: function () {
    
            }}}, [
        h('span', {style: {fontWeight: 'bold'}}, 'This is bold'),
        ' and this is just normal text',
        h('a', {props: {href: '/foo'}}, 'I\'ll take you places!')
    ]);
    // Patch into empty DOM element – this modifies the DOM as a side effect
    patch(container, vnode);
    
    var newVnode = h('div#container.two.classes', {on: {click: function () {
    
            }}}, [
        h('span', {style: {fontWeight: 'normal', fontStyle: 'italic'}}, 'This is now italic type'),
        ' and this is still just normal text',
        h('a', {props: {href: '/bar'}}, 'I\'ll take you places!')
    ]);
    // Second `patch` invocation
    patch(vnode, newVnode); // Snabbdom efficiently updates the old view to the new state

    管他乱不乱直接CV!
    在www下面的index.html还需要加入一个ID为container的盒子
    image.png
    当然如果用不了官方代码就用我的

    /** src/index.js */
    import {
        init,
        classModule,
        propsModule,
        styleModule,
        eventListenersModule,
        h,
    } from "snabbdom";
    
    const patch = init([
        // Init patch function with chosen modules
        classModule, // makes it easy to toggle classes
        propsModule, // for setting properties on DOM elements
        styleModule, // handles styling on elements with support for animations
        eventListenersModule, // attaches event listeners
    ]);
    
    const container = document.getElementById("container");
    
    const vnode = h("div#container.two.classes", { on: { click: () => {} } }, [
        h("span", { style: { fontWeight: "bold" } }, "This is bold"),
        " and this is just normal text",
        h("a", { props: { href: "/foo" } }, "I'll take you places!"),
    ]);
    // Patch into empty DOM element – this modifies the DOM as a side effect
    patch(container, vnode);
    
    const newVnode = h(
        "div#container.two.classes",
        { on: { click: () => {} } },
        [
            h(
                "span",
                { style: { fontWeight: "normal", fontStyle: "italic" } },
                "This is now italic type"
            ),
            " and this is still just normal text",
            h("a", { props: { href: "/bar" } }, "I'll take you places!"),
        ]
    );
    // Second `patch` invocation
    patch(vnode, newVnode); // Snabbdom efficiently updates the old view to the new state

    最后看看运行效果
    image.png
    测试Snabbdom环境成功了!撒花撒花!!

  • TA的每日心情
    无聊
    2023-11-2 17:37
  • 签到天数: 275 天

    [LV.8]以坛为家I

    107

    主题

    438

    回帖

    944

    积分

    荣誉开发者

    积分
    944

    荣誉开发者油中2周年卓越贡献生态建设者

    发表于 2022-7-20 21:17:42 | 显示全部楼层
    ggnb666!!!
    I frequently record, because want to leave something.
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表