同一组件的多个实例,一个具有独特的样式?
Multiple instances of same component, one with unique style?
我正在构建一个包含三个卡片组件的页面。三张牌中的一张(中间一张)的样式与另外两张不同,我无法做到这一点。这是我目前所拥有的...
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.svelte(下)
<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>
App.svelte(下)
<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>
我是 Svelte 的新手,完全被这个难住了。我试过使用 $$restProps
和动态样式,但我似乎无法深入了解我需要的按钮和卡片 div
中嵌套的各种元素。
Svelte 可以做到这一点吗,还是我应该简单地构建另一个组件来满足我的需要?当然还有另一种(更干燥)的方法来做到这一点?非常感谢任何帮助!
有很多不同的方法可以解决这个问题,但我会做如下事情:
在 Card 和 Button 组件中引入一个名为“secondary”的布尔属性。这将默认为 false,但对于中间卡将设置为 true。控制我们是否应用替代样式。 Card 会将其传递给 Button 组件,因此如果 secondary = true
对于 Card,它对于 Button 也等于 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"
等
根据次要道具是否为真,将class“次要”添加到卡片和按钮。 Svelte 的 class directive 让这一切变得简单。
<!-- Card.svelte -->
<div class="card" class:secondary>
<!-- Button.svelte -->
<button class:secondary><slot /></button>
应用以下样式。虽然您为第二张卡片粘贴了许多不同的样式,但唯一发生变化的是背景和文本颜色。我将这些值移至 CSS custom properties。当应用 secondary
class 时,自定义属性会更新,其他所有内容都使用新颜色。
<!-- 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.
中看到最终演示
我正在构建一个包含三个卡片组件的页面。三张牌中的一张(中间一张)的样式与另外两张不同,我无法做到这一点。这是我目前所拥有的...
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.svelte(下)
<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>
App.svelte(下)
<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>
我是 Svelte 的新手,完全被这个难住了。我试过使用 $$restProps
和动态样式,但我似乎无法深入了解我需要的按钮和卡片 div
中嵌套的各种元素。
Svelte 可以做到这一点吗,还是我应该简单地构建另一个组件来满足我的需要?当然还有另一种(更干燥)的方法来做到这一点?非常感谢任何帮助!
有很多不同的方法可以解决这个问题,但我会做如下事情:
在 Card 和 Button 组件中引入一个名为“secondary”的布尔属性。这将默认为 false,但对于中间卡将设置为 true。控制我们是否应用替代样式。 Card 会将其传递给 Button 组件,因此如果
secondary = true
对于 Card,它对于 Button 也等于 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"
等根据次要道具是否为真,将class“次要”添加到卡片和按钮。 Svelte 的 class directive 让这一切变得简单。
<!-- Card.svelte --> <div class="card" class:secondary> <!-- Button.svelte --> <button class:secondary><slot /></button>
应用以下样式。虽然您为第二张卡片粘贴了许多不同的样式,但唯一发生变化的是背景和文本颜色。我将这些值移至 CSS custom properties。当应用
secondary
class 时,自定义属性会更新,其他所有内容都使用新颜色。<!-- 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.
中看到最终演示