VueJ - 슬롯 래핑 요소에 스타일 적용
작성하려고 합니다.Card
vuejs slots api를 사용하는 헤더 및 내용 섹션이 있는 vue 사용 구성 요소
카드 컴포넌트에 구조를 만드는 방법을 이해하지 못하고 있습니다.카드는 모든 와이어프레임 스타일(패딩 및 여백)을 포함해야 하지만 컴포넌트를 사용하는 자 템플릿에서 확장하기 위해 열려 있어야 합니다.
자 부품에서 내부에 슬롯이 있는 래퍼 요소를 스타일링하는 표준 방법이 있는지 알고 싶습니다.
기본Card
요소에는 구조 요소로 둘러싸인 2개의 슬롯이 있습니다.자체 템플릿은 필요에 따라 변경할 수 있습니다.
<div class="Card">
<header class="CardHeader">
<slot name="header"></slot>
</header>
<div class="CardContent">
<slot></slot>
</div>
</div>
이상적으로는 다음 항목을 추가하고 싶습니다.:class
의 탓으로 돌리다#slot
그러나 오래된 구문은 최신 버전의 프레임워크에서 감가상각된 것 같습니다.
<Card>
<template #header class="extendHeader">
stuff
</template>
</Card>
3가지 방법을 생각할 수 있습니다.각각의 단점이 있습니다.
- 소품을 사용하여 루트 요소를 통해 클래스 추가
- 루트 요소에 클래스를 사용하고 구성 요소 요소에 스타일 후크가 있음
- 슬롯 콘텐츠를 다른 요소로 래핑합니다.
제 프로젝트에서 꼭 필요한 것은 css-modules를 사용하여 글로벌 css를 최대한 줄이는 것입니다.왜냐하면 과거에 css-modules는 매우 큰 문제를 일으켰기 때문입니다.
1. 소품을 사용하여 루트 요소를 통해 클래스를 추가합니다.
이 방법을 사용하면 css-modules를 사용할 수 있으며,Card
확장을 위해 열려 있는 요소
구성 요소 템플릿은 하위 템플릿에서 추가 스타일을 구성해야 합니다.
<header :class="$style.Header, ...headerClasses]">
<slot name="header"></slot>
</header>
그러면 하위 템플릿은 다음을 사용할 수 있습니다.:header-classes
기본 카드 클래스를 확장하거나 원하지 않는 스타일을 덮어씁니다.
<Card :header-classes="[$style.header]">
<template #header>
stuff
</template>
</Card>
<style module>
.header {
background: var(--v-blue);
}
</style>
2. 루트 요소에 클래스를 사용하고 구성 요소 요소에 스타일 후크가 있습니다.
그Card
템플릿에서는 컴포넌트의 기본 구조 컴포넌트를 확장하는 데 사용할 수 있는 추가 클래스를 할당해야 합니다.css-module 클래스는 충돌을 피하기 위해 이름이 해시될 때 사용하지 마십시오.
<div :class="[$style.Card, 'CardStyleHook']">
<header :class="[$style.Header, 'CardHeaderStyleHook']">
<slot name="header"></slot>
</header>
<div :class="[$style.Content, 'CardContentStyleHook']">
<slot></slot>
</div>
</div>
그런 다음 단일 클래스를 구성요소에 추가하고 추가 클래스에 스타일을 사용할 수 있습니다.
<Card :class="$style.extendCard">
<template #header>
stuff
</template>
</Card>
<style module>
.extendCard .CardHeaderStyleHook {
background: var(--v-blue);
}
</style>
3. 슬롯의 내용을 다른 요소로 랩합니다.
이것은 슬롯의 목적에 어긋난다고 생각합니다만, 이것은 포장의 구조 요소로부터 패딩을 떼어내는 문제로 이어집니다.Card
확장에 대해서는 오픈되어 있지 않기 때문에, 이 스타일을 사용하려면 , 보다 많은 회피책이 필요합니다.
<Card>
<template #header>
<div :class="$style.customHeader">
stuff
</div>
</template>
</Card>
<style module>
.customHeader{
background: var(--v-blue);
}
</style>
오래된 슬롯이 감가상각되었기 때문에 이러한 케이스에 대한 표준적인 대처 방법이 있습니까?설명서에서 놓친 것이 있습니다.vue를 사용한 지 이틀밖에 안 됐기 때문에 충분히 가능합니다.
다음 스니펫에는 예를 제시해야 할 경우 작업 코드와 함께 완전한 예가 나와 있습니다.
도와주셔서 감사합니다!
const use$styleMocking = {
beforeMount() {
// mock css-modules output
this.$style = {
Card: 'Card__x1337',
Header: 'CardHeader__x1337',
Content: 'CardContent__x1337',
}
}
}
Vue.component('Card', {
template: '#card-template',
mixins: [ use$styleMocking ],
props: {
cardClasses: { default: () => [] },
headerClasses: { default: () => [] },
contentClasses: { default: () => [] },
}
})
Vue.component('style-hooked-card', {
template: '#style-hooked-card-template',
mixins: [ use$styleMocking ]
})
const app = new Vue({
el: '#app',
template: '#app-template'
})
:root {
--white: #fff;
--v-teal: #00c58e;
--v-jade: #108775;
--v-blue: #2f495e;
--card-padding: 0.5rem 1rem;
--grid-gap: 1.25rem;
}
html, body {
font-family: sans-serif;
line-height: 1.44;
}
.main {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-column-gap: var(--grid-gap);
grid-row-gap: var(--grid-gap);
}
/* --------- Card Styles --------- */
/*
styles have __x1337 to mock css-modules, the client should never know the hash
and should not use it to style elements
*/
.Card__x1337 {
box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
transition: 400ms box-shadow;
margin: 0;
flex: 1;
}
.CardHeader__x1337 {
padding: var(--card-padding);
background: var(--v-teal);
}
.CardHeader__x1337 h3 {
color: var(--v-blue);
margin: 0;
padding: 0;
font-size: 1rem;
}
.CardContent__x1337 {
padding: var(--card-padding);
}
/* --------- End Card Styles --------- */
.extendHeader {
background: var(--v-blue);
}
.extendHeader h3 {
color: var(--white);
}
.extendCard .CardHeaderStyleHook {
background: var(--v-jade);
}
.extendCard .CardHeaderStyleHook h3 {
color: var(--white);
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<template type="text/x-template" id="app-template">
<main class="main">
<Card>
<template #header class="extendHeader">
<h3>Basic Card Styles</h3>
</template>
<template>
<p>It would be ideal to add a class to the template and have it available to add to the classes of the wrapper element around slots</p>
</template>
</Card>
<Card :header-classes="['extendHeader']">
<template #header>
<h3>1. Extend Header Styles</h3>
</template>
<template>
<p>This card uses props on the Card to extend the wrapper class, this example is using a global class, but this would use css-modules locally scoped classes correctly</p>
</template>
</Card>
<Style-Hooked-Card class="extendCard">
<template #header>
<h3>2. Extend Card Styles</h3>
</template>
<template>
<p>This card adds a hook class to every component so that it can be extended from the outside</p>
</template>
</Style-Hooked-Card>
</main>
</template>
<template type="text/x-template" id="card-template">
<div :class="[$style.Card, ...cardClasses]">
<header :class="[$style.Header, ...headerClasses]">
<slot name="header"></slot>
</header>
<div :class="[$style.Content, ...contentClasses]">
<slot></slot>
</div>
</div>
</template>
<template type="text/x-template" id="style-hooked-card-template">
<div :class="[$style.Card, 'CardStyleHook']">
<header :class="[$style.Header, 'CardHeaderStyleHook']">
<slot name="header"></slot>
</header>
<div :class="[$style.Content, 'CardContentStyleHook']">
<slot></slot>
</div>
</div>
</template>
<div id="app"></div>
언급URL : https://stackoverflow.com/questions/59590009/vuejs-apply-styles-to-slots-wrapping-elements
'programing' 카테고리의 다른 글
Vue 2.0 $on()으로 마이그레이션해도 $emit()이 들리지 않습니다. (0) | 2022.08.18 |
---|---|
파이어베이스 호스팅을 사용할 때 vuej의 환경 변수에 파이어베이스 구성 매개 변수를 저장하는 방법 (0) | 2022.08.18 |
VueJ의 동적 구성 요소에 대한 사용자 지정 이벤트 프로그래밍 바인딩s (0) | 2022.08.18 |
Vue: Vuex getter에서 Per-Route Guard를 사용하는 방법 (0) | 2022.08.18 |
글로벌 변수 앞에 static 키워드를 사용하는 경우 (0) | 2022.08.18 |