函数式组件是 vue 2 中无实例、无状态、无生命周期的轻量组件,仅通过 props 和 context 渲染 vnode,适用于纯展示场景;需显式声明 functional: true 和 props,禁用 this、data、生命周期等特性。

函数式组件是 Vue 2 中一种轻量、无实例、无状态的组件形式,能显著减少渲染开销,特别适合纯展示类场景。它不创建组件实例,跳过响应式系统追踪和生命周期流程,直接基于传入的 props 渲染 VNode,因此比普通组件更快。
函数式组件的核心特征
理解它的限制和优势,是正确使用的前提:
- 无状态:不能声明 data、computed、watch,也不响应数据变化——输出完全由输入(props)决定
- 无实例:没有 this 上下文,无法访问 methods、$refs、$emit 或生命周期钩子
- 无生命周期:mounted、created 等钩子不可用,也不能使用 beforeDestroy 等清理逻辑
- 依赖 context:props、slots、scopedSlots、attrs、listeners 都通过 render 函数的第二个参数 context 对象获取
如何正确定义一个函数式组件
必须显式声明 functional: true,且模板或 render 函数需适配无实例特性:
- 在单文件组件中,
<template functional></template>即可启用(Vue 2.5+) - 使用 render 函数时,在组件选项中设置
functional: true,并在 render 中接收 context - props 必须显式声明,否则 context.props 为空对象
- 访问插槽要用
context.slots()或context.scopedSlots,不能用this.$slots
适合用函数式组件的典型场景
不是所有组件都适用,关键看是否满足“输入确定输出”这一原则:
- 静态文本包装器:如带 icon 和 label 的按钮封装、标签徽章(Badge)、提示文字(Tip)
- 结构化展示组件:如根据 level 动态生成 h1–h6 的标题组件、带前缀/后缀的输入框包装
- 列表项渲染器:v-for 中每一项只是简单展示字段(如用户头像+昵称),无交互、无状态
- 高频率重绘区域:表格单元格、卡片摘要、图标按钮等被频繁 diff 的节点
实际写法示例与避坑要点
以一个通用图标按钮为例,对比错误写法和正确写法:
-
错误:在模板里写
{{ this.text }}—— 函数式组件没有 this,会报 undefined -
错误:未声明 props 却试图读取
context.props.text—— 声明 props 是强制要求 -
正确:用
render(h, { props, slots }),返回h('button', { attrs: { type: 'button' } }, slots().default) -
注意:如果需要事件透传,需手动绑定
on: { click: props.onClick },不能靠 v-on 自动代理
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











