同一组件的多个实例,一个具有唯一样式



我正在构建一个包含三个卡组件的页面。三张牌中的一张(中间的一张(的风格与其他两张不同,我无法做到这一点。以下是我迄今为止所拥有的。。。

Card.svelte(下图(

<script>
export let subLevel;
export let price;
export let users;
export let storage;
export let sendLimit;
import Button from "./Button.svelte";
</script>
<div class="card">
<h2>{subLevel}</h2>
<ul>
<li class="price"><span class="dollar">$</span>{price}</li>
<li class="spec">{storage} Storage</li>
<li class="spec">{users} Users Allowed</li>
<li class="spec">Send up to {sendLimit} GB</li>
</ul>
<Button>Learn more</Button>
</div>
<style>
.card {
display: flex;
flex-flow: column nowrap;
align-items: center;
padding-top: 2rem;
background-color: #fff;
border-radius: 10px;
max-width: 350px;
color: var(--gray-blue);
padding-inline: 29px;
}
.dollar {
font-size: 2.5rem;
margin-right: 0.5rem;
}
.price {
display: flex;
font-size: 4.5rem;
align-items: center;
justify-content: center;
border-top: none;
color: var(--dark-gray-blue);
}
ul {
width: 100%;
list-style: none;
text-align: center;
}
li {
text-decoration: none;
border-top: 1px solid var(--gray-blue);
padding-block: 13px;
}
li:last-child {
border-bottom: 1px solid var(--gray-blue);
}
</style>

按钮.苗条(下图(

<button><slot /></button>
<style>
button {
text-transform: uppercase;
width: 100%;
background: linear-gradient(135deg, #a2a7f0, #696edd);
color: #fff;
font-size: 0.8125rem;
letter-spacing: 1.39px;
padding-block: 0.875rem;
border: none;
border-radius: 6px;
cursor: pointer;
margin-block: 2rem;
}
</style>

应用程序苗条(下图(

<script>
import Card from "./components/Card.svelte";
import Footer from "./components/Footer.svelte";
// Card details
const basicMonthly = {
subLevel: "Basic",
price: 19.99,
storage: "500 GB",
users: 2,
sendLimit: 3,
};
const proMonthly = {
subLevel: "Professional",
price: 24.99,
storage: "1 TB",
users: 5,
sendLimit: 10,
};
const masterMonthly = {
subLevel: "Master",
price: 39.99,
storage: "2 TB",
users: 10,
sendLimit: 20,
};
</script>
<main class="site-content">
<Card {...basicMonthly} />
<Card {...proMonthly} />
<Card {...masterMonthly} />
</main>
<Footer />
<style>
</style>

我的问题是:如何为第二个Card组件添加独特的样式它应该有以下样式:

中间组件的样式(下图(

<style>
.card {
display: flex;
flex-flow: column nowrap;
align-items: center;
padding-top: 2rem;
background-color: linear-gradient(135deg, #a2a7f0, #696edd);
border-radius: 10px;
max-width: 350px;
color: #fff;
padding-inline: 29px;
}
.dollar {
font-size: 2.5rem;
margin-right: 0.5rem;
}
.price {
display: flex;
font-size: 4.5rem;
align-items: center;
justify-content: center;
border-top: none;
color: #fff;
}
ul {
width: 100%;
list-style: none;
text-align: center;
}
li {
text-decoration: none;
border-top: 1px solid #fff;
padding-block: 13px;
}
li:last-child {
border-bottom: 1px solid #fff;
}
</style>

Button.svelte也必须更改中间组件。它的风格应该如下:

<style>
button {
text-transform: uppercase;
width: 100%;
background: #fff;
color: #6d72de;
font-size: 0.8125rem;
letter-spacing: 1.39px;
padding-block: 0.875rem;
border: none;
border-radius: 6px;
cursor: pointer;
margin-block: 2rem;
}
</style>

我是斯维尔特的新手,完全被这件事难住了。我已经尝试过使用$$restProps和动态样式,但我似乎无法深入了解按钮和嵌套在卡片div中的各种元素

Svelte有可能做到这一点吗?还是我应该简单地构建另一个组件来满足我的需求?肯定还有另一种(更干燥的(方法可以做到这一点吗?非常感谢您的帮助!

有很多不同的方法来解决这个问题,但我会做如下操作:

  1. 引入一个名为";次级";卡和按钮组件。这将默认为false,但对于中间卡将设置为true。控制是否应用替代样式。卡片会将其传递到按钮组件中,因此如果卡片的secondary = true也等于按钮的值。

    export let secondary = false;
    
    <!-- App.svelte -->
    <main class="site-content">
    <Card {...basicMonthly} />
    <Card secondary {...proMonthly} />
    <Card {...masterMonthly} />
    </main>
    <!-- Card.svelte -->
    <!-- ... rest of template -->
    <Button {secondary}>Learn more</Button>
    

    如果您最终有多个不同的变体,那么将其作为字符串可能是有意义的,例如variant="secondary"variant="tertiary"等。

  2. 添加类";次级";根据第二道具是否为真,对卡片和按钮进行设置。Svelte的类指令使这变得容易。

    <!-- Card.svelte -->
    <div class="card" class:secondary>
    <!-- Button.svelte -->
    <button class:secondary><slot /></button>
    
  3. 应用以下样式。当你为第二张卡片粘贴了很多不同的样式时,唯一改变的是背景和文本颜色。我将这些值移动到CSS自定义属性中。应用secondary类时,将更新自定义属性,其他所有内容都使用新颜色。

    <!-- Card.svelte styles -->
    <style>
    .card {
    --background: #fff;
    --text-color: var(--gray-blue);
    display: flex;
    flex-flow: column nowrap;
    align-items: center;
    padding-top: 2rem;
    background: var(--background);
    border-radius: 10px;
    max-width: 350px;
    color: var(--text-color);
    padding-inline: 29px;
    }
    .card.secondary {
    --background: linear-gradient(135deg, #a2a7f0, #696edd);
    --text-color: #fff;
    }
    .dollar {
    font-size: 2.5rem;
    margin-right: 0.5rem;
    }
    .price {
    display: flex;
    font-size: 4.5rem;
    align-items: center;
    justify-content: center;
    border-top: none;
    color: var(--text-color);
    }
    ul {
    width: 100%;
    list-style: none;
    text-align: center;
    }
    li {
    text-decoration: none;
    border-top: 1px solid var(--text-color);
    padding-block: 13px;
    }
    li:last-child {
    border-bottom: 1px solid var(--text-color);
    }
    </style>
    <!-- Button.svelte styles -->
    <style>
    button {
    --background: linear-gradient(135deg, #a2a7f0, #696edd);
    --text-color: #fff;
    text-transform: uppercase;
    width: 100%;
    background: var(--background);
    color: var(--text-color);
    font-size: 0.8125rem;
    letter-spacing: 1.39px;
    padding-block: 0.875rem;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    margin-block: 2rem;
    }
    button.secondary {
    --background: #fff;
    --text-color: #6d72de;
    }
    </style>
    

有了这些更新,就没有重复,也不必创建单独的组件。你可以在这个Svelte REPL中看到最后的演示。

相关内容

最新更新