xgqfrms™, xgqfrms® : xgqfrms's offical website of cnblogs! xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

vue h render function All In One

vue h render function All In One

vue h 渲染函数 All In One

h() 函数是一个用于创建 VNode 的实用程序。
也许可以更准确地将其命名为 createVNode(),但由于频繁使用和简洁,它被称为 h()
它接受三个参数:tag, props, children

  1. {String | Object | Function} tag
  2. {Object} props 可选,
  3. {String | Array | Object} children 可选,

如果没有 prop,那么通常可以将 children 作为第二个参数传入。
如果会产生歧义,可以将 null 作为第二个参数传入,将 children 作为第三个参数传入。

// @returns {VNode}
h(
  // {String | Object | Function} tag
  // 一个 HTML 标签名、一个组件、一个异步组件、或 一个函数式组件。
  //
  // 必需的。
  'div',

  // {Object} props
  // 与 attribute、prop 和事件相对应的对象。
  // 这会在模板中用到。
  //
  // 可选的。
  {},

  // {String | Array | Object} children
  // 子 VNodes, 使用 `h()` 构建,
  // 或使用字符串获取 "文本 VNode" 或者
  // 有插槽的对象。
  //
  // 可选的。
  [
    'Some text comes first.',
    h('h1', 'A headline'),
    h(MyComponent, {
      someProp: 'foobar'
    })
  ]
)

vue 2.x


Vue.component('custom-btn', {
  data() {
    return {
      text: 'Click me',
    };
  },
  methods: {
    handleClick() {
      console.log('clicked 👻');
    },
  },
  render(h) {
    return h('button', {
        attrs: {
          class: 'btn-primary'
        },
        on: {
          click: this.handleClick,
        },
    }, this.text);
  },
});

https://cn.vuejs.org/v2/guide/render-function.html#createElement-参数

JSX

const h = this.$createElement;

将 h 作为 createElement 的别名是 Vue 生态系统中的一个通用惯例,实际上也是 JSX 所要求的。
从 Vue 的 Babel 插件的 3.4.0 版本开始,我们会在以 ES2015 语法声明的含有 JSX 的任何方法和 getter 中 (不是函数或箭头函数中) 自动注入 const h = this.$createElement,这样你就可以去掉 (h) 参数了。
对于更早版本的插件,如果 h 在当前作用域中不可用,应用会抛错。

https://cn.vuejs.org/v2/guide/render-function.html#JSX

https://github.com/vuejs/jsx

vue 3.x


const { createApp, h } = Vue

const app = createApp({})

/** 递归地从子节点获取文本 */
function getChildrenTextContent(children) {
  return children
    .map(node => {
      return typeof node.children === 'string'
        ? node.children
        : Array.isArray(node.children)
        ? getChildrenTextContent(node.children)
        : ''
    })
    .join('')
}

app.component('anchored-heading', {
  render() {
    // 从 children 的文本内容中创建短横线分隔 (kebab-case) id。
    const headingId = getChildrenTextContent(this.$slots.default())
      .toLowerCase()
      .replace(/\W+/g, '-') // 用短横线替换非单词字符
      .replace(/(^-|-$)/g, '') // 删除前后短横线

    return h('h' + this.level, [
      h(
        'a',
        {
          name: headingId,
          href: '#' + headingId
        },
        this.$slots.default()
      )
    ])
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

https://v3.cn.vuejs.org/guide/render-function.html#h-参数

vue 3 & render function

https://vuejs.org/guide/extras/render-function.html

https://staging-cn.vuejs.org/guide/extras/render-function.html

demo

import Vue from "vue";

// 全局注册组件
Vue.component("render-function-btn", {
  data() {
    return {
      text: "Click me",
      count: 0
    };
  },
  methods: {
    handleClick() {
      if (this.count === 0) {
        this.text = "clicked 🚀";
      }
      this.count++;
      console.log("clicked 🚀");
    }
  },
  render(h) {
    // h 渲染函数 (tag, props, children)
    return h("div", {}, [
      h("p", null, `Vue.component & h 渲染函数`),
      h(
        "button",
        {
          attrs: {
            class: "btn-primary"
          },
          on: {
            click: this.handleClick
          }
        },
        `👻 ${this.text} = ${this.count}`
      )
    ]);
    // return h(
    //   "button",
    //   {
    //     attrs: {
    //       class: "btn-primary"
    //     },
    //     on: {
    //       click: this.handleClick
    //     }
    //   },
    //   `👻 ${this.text} = ${this.count}`
    // );
  }
});


https://codesandbox.io/s/strange-christian-fgodtu?file=/src/components/render-function-btn.js:295-301

https://zyszys.github.io/vue-patterns-cn/patterns/#渲染函数

refs



©xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!


posted @ 2022-06-08 14:05  xgqfrms  阅读(57)  评论(2编辑  收藏  举报