내 Vue 관점에서 볼 때: 헤드 없는 구성 요소

안녕하세요.이것은'나의 Vue 관점에서'시리즈의 두 번째 문장으로 우리는 여기서 Vue 중의 재미있는 화제를 토론하고 탐색하며 이해할 것이다.js 투시도.
오늘 우리는 무두 구성 요소를 연구할 것이다. 나는 이것이 중급/고급 주제라고 생각하기 때문에 이전에 Vue에 대한 지식을 가지고 있다.js는 이 개념이 전체적인 것이지만 다른 구조에서 사용할 수 있도록 이 예시들을 더 잘 파악해야 할 것이다.
더 이상 지체하지 말고 우리 시작합시다.

소개하다.


응용 프로그램을 만들 때, 다른 사용자 인터페이스 (UI) 로 같은 논리로 같은 구성 요소를 여러 번 사용하거나, 응용 프로그램 디자인과 전혀 다른 독선적인 디자인을 가진 패키지를 설치하는 것을 발견할 수 있다.입력, 레이블, 버튼 등의 단순 구성 요소를 사용자 정의하는 것은 어렵지 않지만 선택, 탭, 절차 마법사 등 복잡한 구성 요소를 다루는 경우 UI의 유연성을 고려하지 않으면 구성 요소를 만드는 데 약간의 어려움이 있을 수 있습니다. 바로 여기서부터 시작됩니다.

헤드 없는 구성 요소는 무엇입니까?


쉽게 말하면headless 구성 요소는 UI와 분리된 논리와 행위를 처리하는 구성 요소로 개발자가 구성 요소의 외관을 이해하도록 한다.
headless 구성 요소는 값과 함수 (상태와 컨트롤) 를 공개할 수 있습니다. 이 값과 함수는 하위 구성 요소가 그 일부분을 제어하고 상태 값에 따라 UI 결정을 할 수 있도록 합니다.즉, UI에 첨부되지 않고 지원됩니다.
이것은 디자인이 매우 다른 프로젝트 사이에서 구성 요소를 공유하거나 같은 구성 요소를 추가하는 변체에 큰 장점을 제공한다. 예를 들어 구성 요소를 업로드하면 파일을 목록이나 이미지 회전 목마로 업로드할 수 있다.

배경.


이 개념은 신선하지 않다. 이 개념은 이미 몇 년 동안 토론되고 실시되었다. 나는 처음으로Tailwind CSS의 창립자라고 들었다. 그 단체가 내놓은 Headless UI 라이브러리, 예를 들어 downshiftbyKent Dodds도 이런 모델을 사용했다. 단지 몇 가지 예를 들 수 있다.

헤드 없는 구성 요소 만들기


요구 사항 및 방법


이를 설명하기 위해 다음과 같은 요구 사항에 따라 헤더링 없는 구성 요소를 구축합니다.
  • 사용자는 count에 몇 개의 별을 표시해야 하는지 지정할 수 있습니다.
  • 선택한 상태를 공개해야 한다.
  • 덮어쓰기 상태를 노출해야 한다.
  • 이 구성 요소를 구축하려면 Tailwind CSS를 사용하여 Vue 3 () 및 codepen을 온라인 편집기로 만듭니다.

    비밀 번호


    다음은 주요 구성 요소를 정의하는 방법입니다.
    const { ref, defineComponent, createApp, computed } = Vue;
    
    const Rate = defineComponent({
      name: 'rate',
      template: `<div>
            <slot 
                v-for="current in range" 
                :key="current" 
                :current="current+1"
                :selected="isSelected(current+1)"
                :covered="isCovered(current+1)"
                :set-hovered="setHovered"
            >
                {{ current }}
            </slot>
        </div>
      `,
      props: ['modelValue', 'count'],
      setup(props) {
        // state
        const hoveredIndex = ref(0);
        const range = computed(() => {
          return [...Array(props.count).keys()];
        })
    
        const isCovered = (current) => {
          return props.modelValue >= current || hoveredIndex.value >= current;
        }
    
        const isSelected = (current) => {
          return props.modelValue == current;
        }
    
        // state functions
        const setHovered = (current) => {
          hoveredIndex.value = current;
        }
    
        return {
          range,
          isSelected,
          isCovered,
          setHovered
        }
      }
    })
    
    여기서 무슨 일이 일어났는지 설명해 드릴게요. 저희가 세 가지 주요 모듈이 있어요.
    국가.range: 이것은 0에서 우리가 이 예에서 전달한count값[0, 1, 2, 3, 4]까지의 수조이다.hoveredIndex: 마지막 별을 저장하기 위해 마우스를 위에 놓습니다.isSelected: 전달된 값이 현재 속도면true로 돌아갑니다.isCovered: 전달된 값이 현재 속도보다 작으면true로 되돌아갑니다
    컨트롤setHovered: 마우스를 시작할 때의 색인을 설정합니다.
    틀나사
    <div>
          <slot 
              v-for="current in range" 
              :key="current" 
              :current="current+1"
              :selected="isSelected(current+1)"
              :covered="isCovered(current+1)"
              :set-hovered="setHovered"
          >
              {{ current }}
          </slot>
    </div>
    
    이 구성 요소를 알려 드리겠습니다. 헤헤, 렌더링 n 은 아이가 당신에게 전달한 모든 요소로 현재 값을 공개하고, 만약 선택된다면, 덮어쓰이면, 그리고 멈추는 함수를 설정합니다.
    이것이 바로 우리가 다음에 해야 할 일이다.

    구성 요소 사용


    이제 구성 요소를 사용하여 5개의 별을 렌더링하고 별의 색상에 회색 텍스트의 스타일을 제공하지만, 덮어쓰거나 선택하면 노란색이고, 클릭할 때 값을 변경하고, 마우스 멈추기와 마우스 멈추기를 사용하여 멈추는 색인을 변경합니다.
    ...
      <h4 class="mt-4 mb-1 font-bold text-blue-900">How useful was the post?</h4>
       <Rate v-model="rating" :count="5" class="space-x-2 cursor-pointer" v-slot:default="{ selected, covered, current, setHovered }">
         <button 
              @click="rating=current" 
              @mouseover="setHovered(current)"
              @mouseout="setHovered(0)"
              class="font-bold text-gray-400 transition transform cursor-pointer hover:text-yellow-400 hover:scale-110" 
              :class="[(selected || covered) ? 'text-yellow-500': 'text-gray-400']"
          > 
           <i class="fa fa-star" > </i>
         </button>
       </Rate>
    ....
    

    사용자 인터페이스 변경


    비례율


    예를 들어 비례를 바꾸기 위해서 우리는 사용자 인터페이스를 바꾸기만 하고 논리에 손대지 않는다.
      <!-- Scale Rate -->
    ...
      <Rate v-model="scale" :count="10" class="space-x-2 cursor-pointer" v-slot:default="{ current, selected }">
         <button 
            @click="scale=current" 
             class="px-3 py-0.5 font-bold border border-gray-400 transition transform rounded-lg cursor-pointer hover:text-blue-400" 
             :class="{'text-blue-500 border-blue-500 shadow-md ring ring-blue-200': selected}"> 
          {{ current }}
         </button>
       </Rate>
    ...
    

    싱글 리스트


    이번의 또 다른 변화는 수직 3 옵션 목록이다.
        <!-- Single Choice List -->
      <h4  class="mt-4 mb-1 font-bold text-blue-900 mt-5">How often do this case happens to you?</h4>
      <Rate v-model="choice" :count="3" class="flex flex-col space-y-2 cursor-pointer w-full" v-slot:default="{ current, selected }">
         <button 
            @click="choice=current" 
             class="block w-44 text-left px-3 py-0.5 font-bold border border-gray-400 transition transform rounded-lg cursor-pointer hover:text-gray-400" 
             :class="{'text-gray-500 border-gray-500 shadow-md ring ring-gray-200': selected}"> 
              <span class="bg-gray-900 text-white px-1.5 rounded-md py-0.5">
                {{ letters[current - 1] }}
              </span>
              {{ choices[current - 1] }}
         </button>
       </Rate>
    

    이것이 바로 내가 말한 가장 큰 유연성이다👌✨. 마지막 개선으로, 우리는 이 세 가지 용례를 지원하기 위해 패키지 구성 요소를 추가하고, mode 과 유사한 도구를 전달할 수 있으며, 외관이 정의되면 rate, scale, choices 를 받아들이고, 실제 페이지에서 더 적은 코드를 작성할 수 있다.연습시켜줄게.
    당신은 Codepen에서 예시 코드를 볼 수 있습니다

    마무리

  • 헤더 없는 구성 요소는 구성 요소의 논리를 다시 사용하는 방법을 제공하지만 맞춤형 UI의 유연성을 가진다.
  • 프로젝트 간에 복잡한 구성 요소를 공유하는 데 적합하다.
  • 기존 구성 요소에 비해 전체 애플리케이션에서 사용자 정의 UI를 사용하도록 구성 요소를 포장해야 할 수 있습니다.이것이 바로 유연성 비용
  • 나는 네가 그것이 유용하다고 생각해서 나에게 네가 여기에 있거나 관련이 있다는 것을 알게 해 주기를 바란다.읽어주셔서 감사합니다. 즐거운 하루 되세요.

    리소스


  • Headlessui
  • A more advanced implementation
  • 좋은 웹페이지 즐겨찾기