直接说答案,因为vue模板表现力不足,你还在问这个问题说明你压根用不到jsx我举几个例子你就知道了例子1:<CompA :v-bind="props1" v-model="value1" v-if="condition"> <div> .... </div> </CompA> <CompA :v-bind="props2" v-model="value2" v-else> <div> .... </div> </CompA>假如这个if-else中CompA的default slot是一摸一样的,而且这个默认插槽有几百行代码,并且大量引用了this上的变量,解决的方案只有两个a. 一模一样的代码得复制两遍分别作为if分支和else的默认插槽b. 把插槽的代码封装成一个SFC,但是不得不他在this上引用的变量全部作为props传递给他上面两个方案都是很痛苦的,相反如果用用jsx那就太简单了他的代码可能是这样的const sharedChildren = <div>....</div> return condition ? <CompA {...props1} vModel={value1}> { { default: () => sharedChildren } } </CompA> : <CompA {...props2} vModel={value2}> { { default: () => sharedChildren } } </CompA>例子2假如有一个组件Menu当使用它时可以给他传一个插槽,不过有一个限制就是他的插槽内的VNode只能是SubMenu和MenuItem类型的,假如混搭有其他类型的VNode这个组件都不能正常工作所以它使用是大概是像下面这个样子<Menu> <SubMenu> <MenuItem title="1-1"> </MenuItem> <MenuItem title="1-2"> </MenuItem> <MenuItem title="1-3"> </MenuItem> </SubMenu> <MenuItem title="2-1" /> <SubMenu> <MenuItem title="3-1"> </MenuItem> <MenuItem title="3-2"> </MenuItem> <MenuItem title="3-3"> </MenuItem> </SubMenu> </Menu>可能很不巧,这个Menu需要是根据数据动态渲染的,而且数据的数量,和层级都是不确定的,也就是需要用到递归组件。一般用模板我们可能会建立一个SFC组件NestedMenuRenderer.vue<script lang="ts"> type MenuItem = { title: string children: MenuItem[] } const NestedMenuRenderer = defineComponent({ name: 'NestedMenuRenderer', props: { menuItem: { type: Object as PropType<MenuItem> } } }) </script> <template> <Fragment> <SubMenu v-if="menuItem.children.length" :title="menuItem.title"> <NestedMenuRenderer v-for="item in menuItem.children" menuItem="item" /> </SubMenu> <MenuItem v-else :title="menuItem.title"/> </Fragment> </template>的确是完成了任务,可是他会在每个MenuItem和SubMenu外面包一个类型NestedMenuRenderer的VNode所以这个组件不能正常的工作,相反换成了jsx就很简单了.const renderNestedMenu = (menu: MenuItem) => { if(menu.children.length) { return <SubMenu title={menu.title}>{menu.children.map(v => renderNestedMenu(v))}</SubMenu> } else return <MenuItem title={menu.title}/> } const data: MenuItem[] = ...; return (<Menu> {data.map(v => renderNestedMenu(v))} </Menu>)
我举几个例子你就知道了
例子1:
假如这个
if-else
中CompA
的default slot
是一摸一样的,而且这个默认插槽有几百行代码,并且大量引用了this上的变量,解决的方案只有两个if
分支和else
的默认插槽props
传递给他上面两个方案都是很痛苦的,相反如果用用jsx那就太简单了他的代码可能是这样的
例子2
假如有一个组件
Menu
当使用它时可以给他传一个插槽,不过有一个限制就是他的插槽内的VNode
只能是SubMenu
和MenuItem
类型的,假如混搭有其他类型的VNode
这个组件都不能正常工作所以它使用是大概是像下面这个样子
可能很不巧,这个
Menu
需要是根据数据动态渲染的,而且数据的数量,和层级都是不确定的,也就是需要用到递归组件。一般用模板我们可能会建立一个SFC组件
NestedMenuRenderer.vue
的确是完成了任务,可是他会在每个
MenuItem
和SubMenu
外面包一个类型NestedMenuRenderer
的VNode
所以这个组件不能正常的工作,相反换成了jsx就很简单了.