Vue 3.x 渲染函数的使用

发布于 2024-09-18 12:38:12 字数 3538 浏览 20 评论 0

概览

  • h 现在是全局导入,而不是作为参数传递给渲染函数
  • 更改渲染函数参数,使其在有状态组件和函数组件的表现更加一致
  • VNode 现在有一个扁平的 prop 结构

动机

官方英文文档

渲染函数参数

2.x 语法

在 2.x 中, render 函数会自动接收 h 函数 (它是 createElement 的惯用别名) 作为参数:

// Vue 2 渲染函数示例
export default {
  render(h) {
    return h('div')
  }
}

3.x 语法

在 3.x 中, h 函数现在是全局导入的,而不是作为参数自动传递。

import { h, reactive } from 'vue'

export default {
  setup(props, { slots, attrs, emit }) {
    const state = reactive({
      count: 0
    })

    function increment() {
      state.count++
    }

    // 返回渲染函数
    return () =>
      h(
        'div',
        {
          id: 'app',
          onClick: increment
        },
        state.count
      )
  }
}

VNode Prop 格式化

2.x 语法

在 2.x 中, domProps (第二个参数) 包含 VNode prop 中的嵌套列表:

// 2.x
{
  staticClass: 'button',
  class: { 'is-outlined': isOutlined },
  staticStyle: { color: '#34495E' },
  style: { backgroundColor: buttonColor },
  attrs: { id: 'submit' },
  domProps: { innerHTML: '' },
  on: { click: submitForm },
  key: 'submit-button'
}

3.x 语法

在 3.x 中,整个 VNode prop 的结构都是扁平的。使用上面的例子,来看看它现在的样子。

{
  class: ['button', { 'is-outlined': isOutlined }],
  style: [{ color: '#34495E' }, { backgroundColor: buttonColor }],
  id: 'submit',
  innerHTML: '',
  onClick: submitForm,
  key: 'submit-button'
}
  • props that start with on are handled as v-on bindings, with everything after on being converted to all-lowercase as the event name (more on this below)
  • for anything else:
    • If the key exists as a property on the DOM node, it is set as a DOM property;
    • Otherwise it is set as an attribute.

注册组件

2.x 语法

在 2.x 中,注册一个组件后,把组件名作为字符串传递给渲染函数的第一个参数,它可以正常地工作:

// 2.x
Vue.component('button-counter', {
  data() {
    return {
      count: 0
    }
  },
  template: `
    <button @click="count++">
      Clicked {{ count }} times.
    </button>
  `
})

export default {
  render(h) {
    return h('button-counter')
  }
}

3.x 语法

在 3.x 中,由于 VNode 是上下文无关的,不能再用字符串 ID 隐式查找已注册组件。取而代之的是,需要使用一个导入的 resolveComponent 方法:

// 3.x
import { h, resolveComponent } from 'vue'

export default {
  setup() {
    const ButtonCounter = resolveComponent('button-counter')
    return () => h(ButtonCounter)
  }
}

Context-free VNodes

import { h, resolveComponent, resolveDirective, withDirectives } from 'vue'

export default {
  render() {
    const comp = resolveComponent('some-global-comp')
    const fooDir = resolveDirective('foo')
    const barDir = resolveDirective('bar')

    // <some-global-comp v-foo="x" v-bar="y" />
    return withDirectives(
      h(comp),
      [fooDir, this.x],
      [barDir, this.y]
    )
  }
}

上例主要用于编译器生成的输出,因为手动编写的渲染函数代码通常直接导入组件和指令并按值使用它们。

更多信息请参考 渲染函数 API 更改 RFC

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

温折酒

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

linfzu01

文章 0 评论 0

可遇━不可求

文章 0 评论 0

枕梦

文章 0 评论 0

qq_3LFa8Q

文章 0 评论 0

JP

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文