programing

VueJ - 슬롯 래핑 요소에 스타일 적용

bestcode 2022. 8. 18. 23:31
반응형

VueJ - 슬롯 래핑 요소에 스타일 적용

작성하려고 합니다.Cardvuejs 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가지 방법을 생각할 수 있습니다.각각의 단점이 있습니다.

  1. 소품을 사용하여 루트 요소를 통해 클래스 추가
  2. 루트 요소에 클래스를 사용하고 구성 요소 요소에 스타일 후크가 있음
  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

반응형