javascript
原始写法(函数式组件)
在 Vue 3 中,render 是保留属性名,与组件的渲染逻辑直接相关。即使未显式声明:
如果父组件传递了 render 属性,Vue 会优先将其注入到 props 中(类似 key、ref 等内置属性)。
这是 Vue 的内部优化,确保渲染函数能直接访问。
import { h } from 'vue'
const Render = (props, ctx) => {
return props.render ? h(props.render, ctx.attrs, ctx.slots) : ''
}
传递props
import { h, defineProps } from 'vue'
const RenderComponent = (props) => {
const { render, ...rest } = defineProps({
render: {
type: Function,
required: true
},
scope: {
type: Object,
default: () => ({})
}
})
return render ? h(render, rest) : null
}
export default RenderComponent
javascript
export default Render
新写法(使用 defineComponent)
import { defineComponent } from 'vue'
export default defineComponent({
props: ['render'],
setup(props, ctx) {
return () => props.render ? h(props.render, ctx.attrs, ctx.slots) : ''
}
})
主要区别
- 组件类型
原始写法:函数式组件(Functional Component)
无状态(无 this)
无实例生命周期
性能略高(Vue 3 中差异变小)
新写法:标准组件(使用 defineComponent)
有组件实例
完整的生命周期
可以使用 Composition API 的全部功能 - Props 声明
原始写法:隐式接收 props
所有属性都通过 props 参数接收
没有显式的 props 验证
新写法:显式声明 props
通过 props 选项明确声明
可以添加类型验证和默认值 - 渲染机制
原始写法:直接返回渲染结果
函数体本身就是渲染函数
新写法:通过 setup 返回渲染函数
setup 返回一个函数(工厂函数)
每次重新渲染都会调用这个工厂函数 - 上下文访问
原始写法:通过第二个参数 ctx 访问
包含 attrs、slots 和 emit
新写法:通过 setup 的第二个参数访问
同样包含 attrs、slots 和 emit
但组织方式更符合 Composition API 风格 - TypeScript 支持
原始写法:类型推断有限
新写法:更好的 TypeScript 集成
可以明确指定 props 类型
更好的编辑器支持