Vue:h渲染函数性能警告[Non-function value encountered for default slot.]

问题描述

在使用Ant-Design-Vue组件库提供的Table表格组件时,通过columns做列配置,尝试借助customRender渲染枚举类型的字段值时,浏览器开发者工具控制台打印如下警告信息:++Vue warn: Non-function value encountered for default slot. Prefer function slots for better performance.++,
vue性能警告信息

问题分析

既然是Vue爆出的警告,我们就把排查的第一个点放在h渲染函数这里。

项目代码中,原始配置方式如下(注意h渲染函数的第三个参数),其中:

  • AntTag:是Ant-Design-Vue组件库提供的Tag标签组件
  • StatusEnum:是自定义的ts枚举类型

h渲染函数

Vue官网对于h渲染函数的完整参数签名如下,

javascript 复制代码
// 完整参数签名
function h(
  type: string | Component,
  props?: object | null,
  children?: Children | Slot | Slots
): VNode

// 省略 props
function h(type: string | Component, children?: Children | Slot): VNode

type Children = string | number | boolean | VNode | null | Children[]

type Slot = () => Children

type Slots = { [name: string]: Slot }

对h渲染函数的参数解释如下,

第一个参数既可以是一个字符串 (用于原生元素) 也可以是一个 Vue 组件定义

第二个参数是要传递的 prop

第三个参数是子节点

结合以上解释,至少可以得到以下3个结论:

  1. 第一个参数此处传递的是Vue组件------没有问题;
  2. 第二个参数此处传递的是Vue组件的prop参数,结合Ant-Degisn-Vue Tag标签API来看------没有问题;
  3. 第三个参数此处传递的是字符串类型的变量值,而官网文档给出的是"子节点"类型------如何定义"子节点"类型???是不是这个地方出现了问题呢?

Vue官网也给出了对应的解释:

当创建一个组件的 vnode 时,子节点必须以插槽函数进行传递。如果组件只有默认槽,可以使用单个插槽函数进行传递。否则,必须以插槽函数的对象形式来传递。

为了方便阅读,当子节点不是插槽对象时,可以省略 prop 参数。

结合官网给出的如下所示的第3个例子(省略了prop参数),很显然,我们这里的第三个字符串类型参数,看起来并不符合"插槽函数"类型。

javascript 复制代码
import Foo from './Foo.vue'

// 传递 prop
h(Foo, {
  // 等价于 some-prop="hello"
  someProp: 'hello',
  // 等价于 @update="() => {}"
  onUpdate: () => {}
})

// 传递单个默认插槽
h(Foo, () => 'default slot')

// 传递具名插槽
// 注意,需要使用 `null` 来避免
// 插槽对象被当作是 prop
h(MyComponent, null, {
  default: () => 'default slot',
  foo: () => h('div', 'foo'),
  bar: () => [h('span', 'one'), h('span', 'two')]
})

插槽函数

那么,什么是插槽函数?参考Vue官网-传递插槽。给出定义:

插槽函数的返回值同一个正常的渲染函数的返回值一样------并且在子组件中被访问时总是会被转化为一个 vnodes 数组

渲染函数

又回到渲染函数这个话题了,那么Vue官网是如何定义"渲染函数"的呢?

详细可参见:Vue官网-渲染机制部分

解决方案

明确了问题的原因:++h渲染函数的子节点传递,需要以"插槽函数"的形式进行传递++。

问题就好解决了,以下是修改之后的项目代码(注意红框部分),问题解决!
修改后的代码

相关推荐
碎碎念_4925 小时前
SpringBoot + Vue 前后端分离从 0 到 1 完整环境配置流程
vue.js·spring boot·后端
shuaijie05185 小时前
强制修改调用接口的api地址。
javascript·vue.js·ecmascript
JerrySir6 小时前
恶意 npm 包只活了 17 分钟:技术面试里,为什么“升级依赖”还不算止血?
javascript·安全
白帽小阳6 小时前
2026前端面试题!(附答案及解析)
javascript·网络·python·安全·web安全·网络安全·护网行动
这是个栗子6 小时前
前端开发中的常用工具函数(八)
开发语言·前端·javascript
Hilaku6 小时前
Vue 和 React 真正的差距,不在语法,而在团队犯错成本
前端·javascript·程序员
研☆香6 小时前
为什么变量声明在赋值前也能使用?—— 深入理解 JavaScript 变量提升与作用域
开发语言·前端·javascript
柯克七七7 小时前
我把 bug 修得太干净了,测试组以为这个模块本来就没问题
前端·javascript·typescript
Null1557 小时前
浏览器唤起桌面端应用(终极篇)
前端·javascript
妙码生花7 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(三十四):后台初始化请求实现
前端·javascript·go