Vue3을 사용하여 어셈블리 버전 제어를 손쉽게 처리

VueJs는 단순성과 낮은 학습 곡선으로 유명해 초보자부터 고급 개발자까지 앱을 발표하는 데 도움을 준다.
하지만 Vue에 코드 라이브러리를 만드는 데 시간을 들이는 사람은 누구나 알다시피 성장함에 따라 고통도 따르게 된다.그렇기 때문에 한 조직이 기술 채무와 스파게티 코드의 수렁에 빠지기 전에 이런 신축성 문제를 빨리 해결하는 것이 중요하다. 왜냐하면 이런 문제들은 며칠, 몇 주, 심지어 몇 달이 걸려야 바로잡을 수 있기 때문이다.
구성 요소에 대한 버전 제어는 개발자의 자아에 영향을 미칠 수 있는 문제 중 하나이지만'미래 6개월 동안 당신의 생활'을 위해 구성 요소에 대한 버전 제어는 매우 중요한 시간과 에너지 절약 전략이다.
bit.dev과 같은 도구는 이 문제를 잘 처리할 수 있지만 저는 Duck tape와 이쑤시개가 직접 만든 해결 방안을 더 좋아합니다. 그들의 효과는 매달 200달러 이상의 서비스와 마찬가지로 좋습니다.

구성 요소의 버전을 업데이트해야 하는 이유
만약 네가 이 문제를 묻는다면, 너는 새로운 지도자를 얻은 디자인 팀과 교제할 필요가 없다.
만약 당신이 이 문제를 묻는다면, 처음부터 결함이 존재했던 문제를 더욱 효과적으로 처리할 새로운 라이브러리를 아직 찾지 못했을 것이다.
만약 네가 이 문제를 묻는다면, 너는 Vue 회의에 참가한 적이 없다. 떠날 때, "응, 왜 나는 계속 이렇게 하지 않았을까?"라고 생각할 것이다.
다시 말하면, 당신의 코드는 변화가 발생할 것이다. Vue에서 100개의 다른 파일에서 이루어진 구성 요소라면, 코드 라이브러리에서 ctrl+shift+F을 실행할 때, 당신은 매우 불편함을 느낄 것이다.

표준 어셈블리 사용
이 예제에서는 간단한 Vue 버튼 구성 요소를 사용합니다.
<template>
  <button
     :class="['button', { block, color }]"
     @click="$emit('click')">
     <slot />
  </button>
</template>

<script>
import { defineComponent } from '@vue/composition-api'

export default defineComponent({
  name: 'Button',
  props: {
    block: Boolean,
    color: {
      type: String,
      default: 'primary'
  },

  setup(props) {
    const colors = {
      primary: 'green',
      error: 'red',
      secondary: 'purple'
    }

    return {
      color: `style-${colors[props.color] || 'green'}`
    }
  }
})  
만약 네가 새로운 방법으로 색깔을 설정하기로 결정한다면, 일은 까다로워질 것이다.이것은 이름이 붙은 색 표를 사용하지 않고 전달 스타일로 충당합니다.
<template>
  <button
     :class="['button', { block }]"
     :style="buttonStyle"
     @click="$emit('click')">
     <slot />
  </button>
</template>

<script>
  [...]
  props: {
    color: {
      type: String,
      default: 'gray'
  },

  setup(props) {
    return {
      buttonStyle: computed(() => { color: props.color })
    }
  }
}
물론, 이것은 단추 구성 요소를 사용하는 모든 실례를 파괴할 것입니다.

어셈블리 버전 작업
이 문제를 해결하기 위해서 가장 직접적인 해결 방안은 구성 요소의 코드와 구성 요소의 호출 방식 사이에 적절한 방법을 만드는 것이다.
이러한 마음가짐으로 우리는 버전화된 구성 요소를 둘러싸고 봉인할 케이스 구성 요소를 만들 것이다.
아마도 너는 너의 구성 요소를 이렇게 조직하는 것에 익숙해졌을 것이다.
src/
   components/
      VButton.vue
이것은 거의 모든 장면에서 유용할 수 있지만, 우연히 Vue - The Road to Enterprise by Thomas Findlay을 만났을 때 (대규모 Vue 프로그램을 구축하기 시작하면 강력히 권장합니다.) Vue 구성 요소를 구성하는 것이 소화 가능한 코드 라이브러리에 매우 중요하다는 것을 알게 될 것입니다.
Thomas의 개념 중 일부는 어셈블리 버전 제어를 처리하는 데 유용한 조직 전략입니다.
src/
   components/
      global/
         VButton/
            index.vue   <-- shell
            VButton-v1.vue   <-- versioned
이것은 구성 요소를 깔끔하게 유지하는 데 도움이 될 뿐만 아니라, 폴더가 접히면서, 각종 구성 요소 폴더는 내부 셸과 버전화된 구성 요소의 그룹을 구성하는 데 편리한 참고가 될 것이다.

셸 구성 요소 작성
이 단추 구성 요소와 가장 가능한 모든 간단한 구성 요소에 대해 케이스를 구축할 때 우리는 네 가지 주요 일을 처리해야 한다.
  • 패스 아이템
  • ATTR
  • 휴대 발사
  • 슬롯 통과
  • 그러나 먼저 버전 지정 어셈블리 파일의 로드를 처리하는 방법은 다음과 같습니다.
    <template>
      <component :is="buttonComponent">
        Button
      </component>
    </template>
    
    <script>
    import { defineAsyncComponent, defineComponent } from '@nuxtjs/composition-api'
    
    export default defineComponent({
      name: 'VButton',
      props: {
        version: {
          type: String,
          default: 'v1'
        },
      },
    
      setup(props) {
        const versionComponent = (version) => defineAsyncComponent(() => {
          return import(`./VButton-${version}.vue`)
        })
    
        return {
          buttonComponent: ref(versionComponent(props.version)),
        }
      }
    })
    </script>
    
    오랜 시련을 겪은 <component>과 Vue3의 defineAsyncComponent 덕분에 사실상 상당히 쉽게 승진할 수 있었다.
    다음은 처리 도구, 속성 및 발사:
    <template>
      <component
        v-bind="{ ...$attrs, ...$props }"
        :is="nButtonComponent"
        @click="$emit('click')">
        Button
      </component>
    </template>
    
    내장 원소 $attrs$props을 사용하면 속성과 도구가 하위 구성 요소에 쉽게 전달되어 소화된다.
    마지막으로, 슬롯:
    <template>
      <component
        v-bind="{ ...$attrs, ...$props }"
        :is="nButtonComponent"
        @click="$emit('click')">
        <slot
          v-for="(_, name) in $slots"
          :name="name"
          :slot="name" />
      </component>
    </template>
    
    $slots을 사용하는 결함 중 하나는 그것이 동적이지 않다는 것이다. 그러나 이것은 기본적으로 임무를 완성했다.모든 셸은 구성 요소에 특정되어 있기 때문에 필요하면 플러그인을 더욱 명확하게 정의할 수 있습니다.
    이렇게일반적으로 어셈블리를 쉽게 가져올 수 있습니다.import VButton from '@/components/global/VButton단, 구성 요소를 사용할 때, 버전 도구를 전달하면 셸에서 어떤 버전의 구성 요소를 사용할 것인지 알려 줍니다. 이것은 많은 중단을 줄이고, 시간의 추이에 따라 변경을 허용합니다.
    <Button
      color="purple"
      version="v1"
      @click="handleClick">
      Click Me!
    </Button>
    
    주: 이 개념의 MVP입니다.어떤 사람들은 다음과 같은 이유로 이런 방법을 비판할 수 있다.
  • 전 세계적으로 사용할 수 있는
  • 이 아닙니다.
  • 은 순수한 Vue3 렌더링 함수로 작성할 수 있다. (이 예는nuxtjs/compositionapi 플러그인을 사용하는 Nuxt2.15 프로그램에서 나온 것으로 Vue3의 일부 기능이 부족하다. resolveComponent을 포함하여 이 문제를 해결할 수 있다)
  • 더 복잡한 구성요소
  • 에는 도움이 되지 않음
    비록 이것들은 모두 사실이지만, 나는 여전히 이것이 매우 유용한 전략이라고 생각한다. 특히, 만약 당신이 처음부터 자신의 UI를 구축하는 개발자라면.

    업데이트
    코드sandbox를 수정한 후에 저는 작업 예시를 정리했습니다. 이 예시는render 함수를 셸 구성 요소로 사용했습니다.
    주의: 이 Vue3 예시에서 slots은 세 번째 매개 변수로 직접 전달할 수 있지만, Nuxt (compositionapi 플러그인이 있는 Vue2도 있을 수 있음) 에서 map(slots, slot => slot) (lodash 사용) 이 필요합니다.

    업데이트 2
    이 개념을 한동안 사용한 후, 나는 발사라는 아주 까다로운 문제에 부딪혔다.
    emits의 문제는 도구나 속성을 사용하는 것처럼 전달을 직접 처리할 수 있는 방법이 없다는 것이다.
    이로써 셸 구성 요소의 '사용자 친선성' 이 낮아졌다. 모든 셸이 더욱 맞춤형으로 만들어지고 두 개의 구성 요소가 발사되어야 하기 때문이다.
    이것은 가장 좋은 것이 아니다.
    그리고 나는 내가 읽은 Vue의 반모드에 관한 문장이 생각났지만, React에서 흔히 볼 수 있는 문장이 있는데, 함수를 도구로 전달하는 것이다. (나는 그것에 연결된 문장을 찾을 수 있기를 바란다.)
    대신 다음과 같습니다.
    @click="$emit('myFunction', value)
    
    다음과 같이 변경됩니다.
    @click="myFunction(value)"
    
    // in <script>
    props: {
      myFunction: Function
    }
    
    내가 말하고자 하는 것은 이러한 전략은 고급 구성 요소에 매우 도움이 되지만, 매우 저급한 구성 요소, 예를 들어 단추나 입력 패키지는 여전히 두 곳에서 emit를 사용하는 것이 가장 좋고, 이렇게 하면 그들의 이벤트가 쉽게 사용될 수 있다.

    좋은 웹페이지 즐겨찾기