模板不是vue的一个特点吗,为什么现在写组件都用jsx呢

模板不是vue的一个特点吗,为什么现在写组件都用jsx呢

模板不是vue的一个特点吗,为什么现在写组件都用jsx呢


回答:

直接说答案,因为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-elseCompAdefault 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只能是SubMenuMenuItem类型的,假如混搭有其他类型的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>

的确是完成了任务,可是他会在每个MenuItemSubMenu外面包一个类型NestedMenuRendererVNode所以这个组件不能正常的工作,相反换成了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>)


回答:

这个问题可以理解为「为啥大家不用/要用 dsl」
那就是「入门成本高、小众但高效」和「低入门成本、复杂」的取舍了

以上是 模板不是vue的一个特点吗,为什么现在写组件都用jsx呢 的全部内容, 来源链接: utcz.com/p/937216.html

回到顶部