在流行的JS框架中的CSS处理的比较
#css #vue #svelte #solidjs

曾是VUE开发人员,因为早期的VUE 2版本并没有阻止我深入研究趋势新的JS框架的比较,尤其是Svelte和Solid,我都喜欢实施消失的框架范式,开创性的框架范式由Svelte撰写,由Solid精炼,并宣布将在VUE和Vapor模式下很快使用。有趣的是,这么多开发人员说,他们更喜欢Svelte而不是替代品,只是因为它是优雅的API,而仅仅是因为信号(在Vue之前就可以使用)。对我来说感觉很肤浅...但是无论如何,这是另一个故事。今天,我想强调一件事,我认为是一个非常有力的论点,更喜欢Vue。随意找到它一样肤浅; - )

想象您有两个组件,一个组件使用另一个组件。您希望消费(儿童)组件的根元素具有自己的类,但能够添加消费(父)组件的类

在Vue中合并的班级

它和vue一样简单

// ComponentA.vue
<script setup>
import ComponentB from './ComponentB.vue'
</script>

<template>
<ComponentB class="a" />
</template>

// ComponentB.vue
<template>
<div class="b">Hello B</div>
</template>

将导致所需的HTML

<div class="a b"></div>

这是由于以下事实,即将传递给组件的任何非prop属性应用于使用的组件的根标签以及类属性的一些额外逻辑。值得注意的是,对于那些不喜欢它的人,这种行为是可以自定义的。

CSS课程合并

如果您尝试在Svelte中做同样的事情,它根本无法正常工作

// ComponentA.svelte
<script>
  import ComponentB from './ComponentB.svelte'
</script>

<ComponentB class="a" />

// ComponentB.svelte
<div class="b">Hello B</div>

打字稿告诉您为什么(如果您正在使用)
Type 'string' is not assignable to type 'never'
换句话说,class不是ComponentB

的道具键

因此,您想像这样修复它

// ComponentB.svelte
<script>
export let class;
</script>

<div class="b">Hello b</div>

但这不起作用,class是javascript中的关键字!

所以您要做的就是更改道具名称,让我们遵循流行的框架的命名:

// ComponentA.svelte
<script>
  import ComponentB from './ComponentB.svelte'
</script>

<ComponentB className="a" />

// ComponentB.svelte
<script>
export let className = '';
</script>

<div class="b">Hello b</div>

仍然不起作用(如果class不是关键字,甚至不起作用),因为我们现在必须合并课程。
我切换到打字稿,以便我们不要忘记提到在TS Land中您还必须告诉编译器,这是一个字符串,除非在这种情况下,您将空字符串作为默认值并获得推断为一个不错的一面效果。

// ComponentB.svelte
<script lang="ts">
  export let className: string = ''
</script>

<div class={`${className} b`}>Hello b</div>

很多样板,不是吗?当然,如果样板不吓到您,并且您喜欢关于道具来自何处和去向的明确性,那没问题。但是,如果您必须食用别人的组成部分,请想象一下ComponentB来自图书馆,而必须撰写ComponentA。您可以肯定地说,一个不提供任何API来将CSS类添加到其组件的组件库是有缺陷的,并且可以提出拉的请求和问题,但这始终是一个缓慢的过程。

CSS课程合并固体

这里的情况与Svelte根本没有不同。

const ComponentB = (props: { class?: string }) => {
  return <div class={`${props.class || ''} b`}>Hello b</div>
}

const ComponentA = () => {
  return <ComponentB class="a" />
}

至少我们可以在这里称其为class

流行组件库中的解决方案

同样的问题适用于Sivte和Solid的样式属性(顺便说一句,也是反应),而Vue再次智能地自动使用具有明确的行为。

在MUI中,流行的React材料组件库,使用sx属性解决了内联样式的自定义问题。但是,尝试将类元素添加到MUI组件中...

并不那么直接。

结论

如果您像我一样,认为在HTML标签中添加类时的开发速度比对以更多样板的价格确定组件CSS的道具完全明确性更为重要,您应该认为这是一个重要的选择下一个Web应用程序框架时的区别。就我个人而言,我从来没有经历过,CSS课程或样式来自Vue Apps中很难进行调试,所以我无法想象像其他框架这样做的方式。