美文网首页vue
Snabbdom 基本使用

Snabbdom 基本使用

作者: 浅忆_0810 | 来源:发表于2021-08-14 23:02 被阅读0次

    1. 创建项目

    • 打包工具为了方便使用 parcel

    • 创建项目,并安装 parcel

      # 创建项目目录
      md snabbdom-demo
      # 进入项目目录
      cd snabbdom-demo
      # 创建 package.json
      npm init -y
      # 本地安装 parcel
      npm install parcel-bundler -D
      
    • 配置 package.jsonscripts

      "scripts": {
        "dev": "parcel index.html --open",
        "build": "parcel build index.html"
      }
      
    • 创建目录结构

      │  index.html
      │  package.json
      └─src
            01-basicusage.js
      

    2. 安装 Snabbdom

    npm install snabbdom@2.1.0
    

    3. 导入 Snabbdom

    Snabbdom的两个核心函数 inith()

    • init() 是一个高阶函数,返回 patch()
    • h() 返回虚拟节点 VNode,这个函数我们在使用 Vue.js 的时候见过
    import { init } from 'snabbdom/init'
    import { h } from 'snabbdom/h'
    const patch = init([])
    

    注意:此时运行的话会告诉我们找不到 init / h 模块,因为模块路径并不是 snabbdom/int,这个路径是在 package.json 中的 exports 字段设置的,而我们使用的打包工具不支持 exports 这个字段,webpack 4 也不支持,webpack 5 支持该字段。该字段在导入 snabbdom/init 的时候会补全路径成 snabbdom/build/package/init.js

    "exports": {
        "./init": "./build/package/init.js",
        "./h": "./build/package/h.js",
        "./helpers/attachto": "./build/package/helpers/attachto.js",
        "./hooks": "./build/package/hooks.js",
        "./htmldomapi": "./build/package/htmldomapi.js",
        "./is": "./build/package/is.js",
        "./jsx": "./build/package/jsx.js",
        "./modules/attributes": "./build/package/modules/attributes.js",
        "./modules/class": "./build/package/modules/class.js",
        "./modules/dataset": "./build/package/modules/dataset.js",
        "./modules/eventlisteners": "./build/package/modules/eventlisteners.js",
        "./modules/hero": "./build/package/modules/hero.js",
        "./modules/module": "./build/package/modules/module.js",
        "./modules/props": "./build/package/modules/props.js",
        "./modules/style": "./build/package/modules/style.js",
        "./thunk": "./build/package/thunk.js",
        "./tovnode": "./build/package/tovnode.js",
        "./vnode": "./build/package/vnode.js"
      }
    

    如果使用不支持 package.jsonexports字段的打包工具,我们应该把模块的路径写全

    import { h } from 'snabbdom/build/package/h'
    import { init } from 'snabbdom/build/package/init'
    import { classModule } from 'snabbdom/build/package/modules/class'
    
    • 回顾 Vue中的 render函数
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
    
    • thunk() 是一种优化策略,可以在处理不可变数据时使用

    4. 代码演示

    4.1 基本使用

    import { h } from 'snabbdom/build/package/h'
    import { init } from 'snabbdom/build/package/init'
    
    // 使用 init() 函数创建 patch()
    // init() 的参数是数组,将来可以传入模块,处理属性/样式/事件等
    let patch = init([])
    
    // 使用 h() 函数创建 vnode
    // 第一个参数:标签+选择器
    // 第二个参数:如果时字符串就是标签中的文本内容
    let vnode = h('div.cls', [
      h('h1', 'Hello Snabbdom')
    ])
    
    const app = document.querySelector('#app')
    /*
      把 vnode 渲染到空的 DOM 元素(替换)
      第一个参数:旧的 VNODE,可以是 DOM 元素
      第二个参数:新的 VNODE
      会返回新的 vnode
    */
    let oldVnode = patch(app, vnode)
    
    setTimeout(() => {
      vnode = h('div.cls', [
        h('p', '这是段落')
      ])
      // 把老的视图更新到新的状态
      oldVnode = patch(oldVnode, vnode)
      
      /*
        清除 div中的内容
        h('!') 是创建空的注释节点
      */
      patch(oldVnode, h('!'))
    }, 2000)
    

    5. 模块

    Snabbdom的核心库并不能处理 DOM元素的属性/样式/事件等,如果需要处理的话,可以使用模块

    5.1 常用模块

    • 官方提供了 6 个模块

      • attributes
        • 设置 DOM元素的属性,使用 setAttribute()
        • 处理布尔类型的属性
      • props
        • attributes 模块相似,设置 DOM元素的属性 element[attr] = value
        • 不处理布尔类型的属性
      • class
        • 切换类样式
        • 注意:给元素设置类样式是通过 sel 选择器
      • dataset
        • 设置 data-* 的自定义属性
      • eventlisteners
        • 注册和移除事件
      • style
        • 设置行内样式,支持动画
        • delayed/remove/destroy

    5.2 模块使用

    模块使用步骤:

    • 导入需要的模块
    • init() 中注册模块
    • 使用 h() 函数创建 VNode的时候,可以把第二个参数设置为对象,其他参数往后移

    5.3 代码演示

    import { h } from 'snabbdom/build/package/h'
    import { init } from 'snabbdom/build/package/init'
    // 导入需要的模块
    import { styleModule } from 'snabbdom/build/package/modules/style'
    import { eventListenersModule } from 'snabbdom/build/package/modules/eventlisteners'
    
    // 使用 init() 函数创建 patch()
    // init() 的参数是数组,将来可以传入模块,处理属性/样式/事件等
    let patch = init([
      // 注册模块
      styleModule,
      eventListenersModule
    ])
    
    // 使用 h() 函数创建 vnode
    // 第一种写法
    let vnode = h('div.cls', [
      h('h1', { style: { color: '#DEDEDE', backgroundColor: '#181A1B' }} ,'Hello Snabbdom'),
      h('p', { on: { click: clickHandler }} ,'这是段落')
    ])
    /*
    // 第二种写法
    let vnode = h('div.cls', {
      // 设置 DOM 元素的行内样式
      style: { color: '#DEDEDE', backgroundColor: '#181A1B' },
      // 注册事件
      on: { click: clickHandler }
    }, [
      h('h1', 'Hello Snabbdom'),
      h('p', '这是段落')
    ])
    */
    
    function clickHandler () {
      // 此处的 this 指向对应的 vnode
      console.log(this.elm.innerHTML)
    }
    

    相关文章

      网友评论

        本文标题:Snabbdom 基本使用

        本文链接:https://www.haomeiwen.com/subject/vsksvltx.html