Vue Enterprise Mode - Design System 변형을 사용하여 구성 요소를 구축하고 변형 스타일을 사용하여 프로그램을 통해 이를 공유하는 방법

35646 단어
본문은 최초로 발표되었다The Road To Enterprise.
많은 프로젝트, 특히 대형 프로젝트는 하나의 디자인 시스템을 가지고 있어 구성 요소의 외관과 느낌을 지도할 수 있다.버튼을 예로 들자.다음은 Figma에서 서로 다른 단추 변체의 빠른 디자인을 볼 수 있습니다.

사이트의 주요 조작에 있어 버튼은 서로 다른 변체를 가질 수 있는데 예를 들어 메인 버튼과 보조 버튼이다.경고나 위험 같은 변체도 있는데, 사용자가 곧 취할 행동에 대해 신중해야 한다.여러 가지 방법으로 변체를 실현할 수 있다.CSS 변수와 모듈을 효율적이고 깔끔하게 사용하는 방법을 여러분과 공유하고 싶습니다.
이 자습서에서는 다음을 설명합니다.
  • 디자인 시스템을 바탕으로 변형된 단추와 태그 구성 요소를 만드는 방법.
  • 어떻게 CSS 변수와 CSS 모듈을 이용하여 구성 요소의 변체를 실현합니까?
  • VariantStyleProvider 어셈블리를 사용하여 여러 어셈블리 간에 변형 스타일을 공유하는 방법
  • 프로젝트 설정


    GitHub 저장소는 전체 코드 예제here를 통해 찾을 수 있습니다.나는 Vite를 사용하여 이 강좌를 위해 새로운 프로젝트를 구축했다.이 자습서를 학습하려면 다음 명령 중 하나를 실행하여 Vite를 사용하여 새 항목을 만들 수 있습니다.
    NPM 지원:
    $ npm init @vitejs/app
    
    실로:
    $ yarn create @vitejs/app
    
    프로젝트를 만든 후 의존 항목을 설치하고 dev 서버를 시작합니다.
    BaseButton.vue 구성 요소를 만드는 것부터 시작합시다.
    src/components/BaseButton.vue
    <template>
      <button :class="[$style.baseButton]" v-bind="$attrs">
        <slot />
      </button>
    </template>
    
    <script>
    export default {
      props: {
        variant: {
          type: String,
          validators: value =>
            ['primary', 'secondary', 'warning', 'danger'].includes(value),
        },
      },
    }
    </script>
    
    <style module>
    .baseButton {
      border: none;
      background: transparent;
      padding: 0.6rem 1rem;
    }
    </style>
    
    이것은 매우 간단한 조립품으로 단지 하나의 도구variant만 있다.이제 App.vue 구성 요소의 내용을 바꾸고 변체마다 네 개의 단추를 추가합니다.
    src/App.vue
    <template>
      <div :class="$style.container">
        <BaseButton variant="primary"> Primary </BaseButton>
        <BaseButton variant="secondary"> Secondary </BaseButton>
        <BaseButton variant="warning"> Warning </BaseButton>
        <BaseButton variant="danger"> Danger </BaseButton>
      </div>
    </template>
    
    <script>
    import BaseButton from './components/BaseButton.vue'
    export default {
      components: {
        BaseButton,
      },
    }
    </script>
    
    <style module>
    .container {
      width: 300px;
      margin: 2rem auto;
      display: grid;
      gap: 1.5rem;
      grid-template-columns: repeat(4, 1fr);
      justify-content: center;
    }
    </style>
    
    위에서 보듯이, 우리는 모든 변체에 네 개의 BaseButton 구성 요소를 보여 줍니다. 주요, 부차적, 경고와 위험입니다.
    다음 그림은 버튼의 현재 모양을 보여 줍니다.메인 화면은 초점을 맞추기 때문에 기본 윤곽 색을 표시합니다.

    나는 이것이 아무것도 아니라는 것을 알고 있지만, 우리는 성공할 것이다.기본 설정이 있기 때문에 BaseButton 구성 요소의 모든 변체에 CSS 변수와 스타일을 추가합니다.범위 양식을 사용하지 않았습니다 (<style scoped>.대신 CSS 모듈을 사용합니다: <style module>.이런 식으로 정의된 모든 스타일은 $style 속성 아래의 구성 요소에 표시됩니다.

    CSS 변수 및 BaseButton 구성 요소 변수


    먼저 variables.css라는 새 파일을 만들고 다음과 같은 CSS 변수를 추가합니다.
    src/스타일/변수.css
    :root {
      --primary-text-color: #eff6ff;
      --primary-bg-color: #1d4ed8;
      --secondary-text-color: #1d4ed8;
      --secondary-bg-color: #eff6ff;
      --warning-text-color: #c2410c;
      --warning-bg-color: #fff7ed;
      --danger-text-color: #b91c1c;
      --danger-bg-color: #fee2e2;
    }
    
    variables.css 파일에서 main.js 파일을 가져옵니다. 프로그램의 구성 요소가 접근할 수 있어야 하기 때문입니다.
    src/main.js
    import { createApp } from 'vue'
    import './styles/variables.css'
    import App from './App.vue'
    
    createApp(App).mount('#app')
    
    다음에 우리는 BaseButton 구성 요소를 업데이트해야 한다.우리는 세 가지 일을 해야 한다.
  • variant 아이템에 변체 스타일을 추가합니다.
  • colorbackground-color속성을 baseButton류에 추가합니다.
  • 각 변수 클래스에 CSS 변수를 추가합니다.
  • src/components/BaseButton.vue
    우선, button 요소에 전달되는 클래스를 변경합니다.baseButton류를 제외하고는 적당한 변체류도 받아들여야 한다.이 레벨은 variant 아이템에 의해 결정됩니다.
    <template>
      <button :class="[$style.baseButton, $style[variant]]" v-bind="$attrs">
        <slot />
      </button>
    </template>
    
    다음에 우리는 colorbackground-color 속성을 baseButton류에 추가할 것이다.이러한 속성에는 --btn-text-color--btn-bg-color 변수가 값으로 사용됩니다.이러한 변수는 각 변수 클래스에서 설정되며 variables.css 파일에 정의된 CSS 변수에 해당합니다.
    <style module>
    .baseButton {
      border: none;
      padding: 0.6rem 1rem;
      color: var(--btn-text-color);
      background-color: var(--btn-bg-color);
    }
    
    .primary {
      --btn-text-color: var(--primary-text-color);
      --btn-bg-color: var(--primary-bg-color);
    }
    
    .secondary {
      --btn-text-color: var(--secondary-text-color);
      --btn-bg-color: var(--secondary-bg-color);
    }
    
    .warning {
      --btn-text-color: var(--warning-text-color);
      --btn-bg-color: var(--warning-bg-color);
    }
    
    .danger {
      --btn-text-color: var(--danger-text-color);
      --btn-bg-color: var(--danger-bg-color);
    }
    </style>
    
    좋습니다. App.vue 구성 요소에서 렌더링한 모든 단추는 아래 그림과 같이 적당한 색을 적용해야 합니다.

    원하는 경우 스톱, 활성 또는 비활성화 등 다양한 상태에 더 많은 변수를 추가할 수 있습니다.
    우리는 첫 번째 목표를 실현했다.우리는 다양한 변체를 지원하는 단추 구성 요소가 있습니다.그러나 만약 우리가 같은 변체를 지원해야 하는 다른 구성 요소를 만들어야 한다면 어떻게 해야 합니까?예를 들어, 태그 어셈블리?어떻게 대처해야 할지 봅시다.

    변형이 있는 BaseTag 구성 요소


    생성BaseTag.vue 구성 요소부터 시작하여 변형마다 표시된 구성 요소를 업데이트합니다.
    src/components/BaseTag.vue
    <template>
      <div :class="[$style.baseTag, $style[variant]]" v-bind="$attrs">
        <slot />
      </div>
    </template>
    
    <script>
    export default {
      props: {
        variant: {
          type: String,
          validators: value =>
            ['primary', 'secondary', 'warning', 'danger'].includes(value),
        },
      },
    }
    </script>
    
    <style module>
    .baseTag {
      border: none;
      border-radius: 1.5rem;
      padding: 0.6rem 1rem;
      color: var(--tag-text-color);
      background: var(--tag-bg-color);
    }
    
    .primary {
      --tag-text-color: var(--primary-text-color);
      --tag-bg-color: var(--primary-bg-color);
    }
    
    .secondary {
      --tag-text-color: var(--secondary-text-color);
      --tag-bg-color: var(--secondary-bg-color);
    }
    
    .warning {
      --tag-text-color: var(--warning-text-color);
      --tag-bg-color: var(--warning-bg-color);
    }
    
    .danger {
      --tag-text-color: var(--danger-text-color);
      --tag-bg-color: var(--danger-bg-color);
    }
    </style>
    
    src/App.vue
    <template>
      <div :class="$style.container">
        <BaseButton variant="primary"> Primary </BaseButton>
        <BaseButton variant="secondary"> Secondary </BaseButton>
        <BaseButton variant="warning"> Warning </BaseButton>
        <BaseButton variant="danger"> Danger </BaseButton>
      </div>
      <div :class="$style.container">
        <BaseTag variant="primary"> Primary </BaseTag>
        <BaseTag variant="secondary"> Secondary </BaseTag>
        <BaseTag variant="warning"> Warning </BaseTag>
        <BaseTag variant="danger"> Danger </BaseTag>
      </div>
    </template>
    
    <script>
    import BaseButton from './components/BaseButton.vue'
    import BaseTag from './components/BaseTag.vue'
    export default {
      components: {
        BaseButton,
        BaseTag,
      },
    }
    </script>
    
    이 업데이트를 한 후에 화면에 네 개의 단추와 네 개의 탭이 보일 것입니다. 아래 그림과 같습니다.

    통할 수 있지, 그렇지?그러나 App.vueBaseButton 구성 요소가 얼마나 비슷한지 발견하셨습니까?그것들은 거의 똑같다. 우리는 상당히 많은 스타일 코드를 중복한다.또 다른 문제가 하나 있다.만약 우리가 두 개 이상의 구성 요소에 변수가 있다면, 예를 들어 20개가 있고, 그 다음에 더 많은 변수를 도입하거나, 기존의 변수를 서로 다른 CSS 변수로 업데이트하면 어떻게 될까요?모든 변형된 구성 요소는 단독으로 업데이트해야 한다.우리는 BaseTagBaseButton 구성 요소에서 변체를 꺼내서 이러한 문제를 해결할 수 있다.반대로, 우리는 새로운 구성 요소를 만들 것입니다. 이 구성 요소는 변형을 관리하고 BaseTag 를 통해 적당한 스타일을 전달할 것입니다.

    Vue 애플리케이션을 개발하는 고급 모델, 기술 및 모범 사례를 배우고 싶으십니까?보기Vue - The Road To Enterprise, 이것은 가장 선진적인 Vue 서적이다.

    VariantStyleProvider 어셈블리와 변형 스타일을 공유하는 방법


    CSS 모듈의 진정한 위대함은 우리가 쉽게 양식을 전달하고 조합할 수 있다는 데 있다.이것이 바로 우리가 지금 해야 할 일이다.먼저 slots라는 새 구성 요소를 생성합니다.이 구성 요소는 다음 세 가지 작업을 수행합니다.
  • 아이템VariantStyleProvider.vue 수령
  • 정의variantcolor 특성
  • 의 변형 양식
  • 렌더링 슬롯 및 채널background-color 및 해당 클래스baseVariant
  • src/components/VariantStyleProvider.vue
    <template>
      <slot :variantStyle="[$style.baseVariant, $style[variant]]" />
    </template>
    
    <script>
    export default {
      props: {
        variant: {
          type: String,
          validators: value =>
            ['primary', 'secondary', 'warning', 'danger'].includes(value),
        },
      },
    }
    </script>
    
    <style module>
    .baseVariant {
      color: var(--variant-text-color);
      background-color: var(--variant-bg-color);
    }
    
    .primary {
      --variant-text-color: var(--primary-text-color);
      --variant-bg-color: var(--primary-bg-color);
    }
    
    .secondary {
      --variant-text-color: var(--secondary-text-color);
      --variant-bg-color: var(--secondary-bg-color);
    }
    
    .warning {
      --variant-text-color: var(--warning-text-color);
      --variant-bg-color: var(--warning-bg-color);
    }
    
    .danger {
      --variant-text-color: var(--danger-text-color);
      --variant-bg-color: var(--danger-bg-color);
    }
    </style>
    
    variant 구성 요소가 현재 변형 스타일을 처리하고 있기 때문에 VariantStyleProviderBaseButton 구성 요소에서 삭제할 수 있습니다.스타일을 삭제하는 것 외에 가져오는 것 BaseTag 과 전달하는 것 VariantStyleProvider 을 사용해야 합니다.다음은 이 두 구성 요소의 최종 버전을 볼 수 있습니다.
    src/components/BaseButton.vue
    <template>
      <VariantStyleProvider :variant="variant">
        <template #default="{ variantStyle }">
          <button :class="[$style.baseButton, variantStyle]" v-bind="$attrs">
            <slot />
          </button>
        </template>
      </VariantStyleProvider>
    </template>
    
    <script>
    import VariantStyleProvider from './VariantStyleProvider.vue'
    
    export default {
      components: {
        VariantStyleProvider,
      },
      props: {
        variant: {
          type: String,
          validators: value =>
            ['primary', 'secondary', 'warning', 'danger'].includes(value),
        },
      },
    }
    </script>
    
    <style module>
    .baseButton {
      border: none;
      padding: 0.6rem 1rem;
    }
    </style>
    
    src/components/BaseTag.vue
    <template>
      <VariantStyleProvider :variant="variant">
        <template #default="{ variantStyle }">
          <div :class="[$style.baseTag, variantStyle]" v-bind="$attrs">
            <slot />
          </div>
        </template>
      </VariantStyleProvider>
    </template>
    
    <script>
    import VariantStyleProvider from './VariantStyleProvider.vue'
    
    export default {
      components: {
        VariantStyleProvider,
      },
      props: {
        variant: {
          type: String,
          validators: value =>
            ['primary', 'secondary', 'warning', 'danger'].includes(value),
        },
      },
    }
    </script>
    
    <style module>
    .baseTag {
      border: none;
      border-radius: 1.5rem;
      padding: 0.6rem 1rem;
    }
    </style>
    
    이 두 부품은 지금 많이 깨끗해졌다.우리는 변체 양식이 variantStyle 구성 요소에서 관리되기 때문에 불필요한 코드 중복을 없애려고 했다.이런 모델은 변체를 유지하고 확장하는 데 도움이 된다.그것들을 업데이트하거나 새로운 것을 추가할 필요가 있다면, 변형을 사용하는 모든 구성 요소를 수동으로 업데이트하는 것이 아니라, VariantStyleProvidervariables.css 두 개의 파일을 주목하십시오.
    나는 네가 이 문장을 좋아하길 바란다.Vue와 관련된 고급 모델, 기술, 최선의 실천에 대해 더 알고 싶다면, 이 책을 보고 싶을 수도 있다.

    좋은 웹페이지 즐겨찾기