这里我们可以直接打印出组件函数,查看vue对两者的不同处理
const Tagsub = (context) => ( <div> { context.props.title } </div> )
console.log(Tagsub)
/**
* {
functional: true,
name: "Sub",
render(h, context){...}
}
*/
function Fnsub(h, title){
return ( <div> { title } </div> )
}
console.log(Fnsub)
/**
ƒ Fnsub(h, title) {
return h("div", [" ", title, " "]);
}
*/
通过比较我们知道,vue 对不同编写方式的不同解析,造成了不同的调用方式, 所以虽然都是函数式组件, 但
标签模式
不能直接通过函数的方式调用,因为已经被编译成类 而函数模式
需要传入 createElement 函数, 且不能作为标签直接调用,应为无法获取到 createElement函数 除此外,两者获取的参数也是有所不同.
jsx 中没有
<slot />
标签, 我们可以通过高阶函数 或$scopedSlots
属性 提供组件嵌套功能
// vue 原生提供插槽属性, 我们可以直接使用该属性 实现嵌套
// 设置作用域插槽
const Article = context => {
// 因为需要获取参数,所以作用域插槽返回函数
const titleSlot = context.scopedSlots.title
const contentSlot = context.scopedSlots.content
return (
<div>
{ titleSlot({title: 'article title'}) }
{ contentSlot({content: 'article content'}) }
</div>
)
}
// 使用1: 标签
<template>
<Article>
<h1 slot='title' slot-scope="slotProps">
{{ slotProps.title }}
</h1>
<p slot='content' slot-scope="slotProps">
{{ slotProps.content }}
</p>
</Article>
</template>
<script>
export default {
components: {
Article
}
}
</script>
// 使用2:jsx
{
render(h){
const scopedSlots = {
title: data => (<h1> { data.title } </h1>),
content: data => ( <p> { data.content } </p> )
}
return (
<Article scopedSlots={ scopedSlots } />
)
}
}