Vue 3의 HOC(고차 구성 요소)

13702 단어 vuejavascript
구성 요소를 재사용하는 고급 기술에 대해 이야기하겠습니다. 그 기능은 구성 요소를 가져와서 새 구성 요소를 되돌려줍니다. 아이디어는 react 커뮤니티here's the link에서 나왔습니다. 이 아이디어는 모든 프로젝트에 유용하지 않을 수 있지만 타사 라이브러리의 경우 훌륭한 패턴입니다.

프로젝트 초기화



좋아, 빠르기 때문에 vite로 프로젝트를 만들 것입니다. more details about vite . 이 명령을 사용하여 프로젝트 생성

npm init @vitejs/app myapp
cd myapp
npm install
npm run dev

// or yarn 
yarn create @vitejs/app myapp
cd myapp
yarn
yarn dev


이름이 첫 번째 구성 요소에 카운터를 하나 더하고 두 번째 구성 요소에 카운터를 5만큼 더하기 때문에 counter CounterPlusOne.vueCounterPlusFive.vue에 대해 두 개의 구성 요소를 생성합니다. 구성 요소는 간단하며 다음과 같이 표시됩니다.

<!-- CounterPlusOne.vue -->
<template>
  <p>counter {{ counter }}</p>
  <button @click="increment">add</button>
</template>

<script>
export default {
  data: () => ({
    counter: 0,
  }),

  methods: {
    increment() {
      this.counter += 1;
    },
  },
};
</script>

<!-- CounterPlusFive.vue -->
<template>
  <p>counter {{ counter }}</p>
  <button @click="increment">add</button>
</template>

<script>
export default {
  data: () => ({
    counter: 0,
  }),

  methods: {
    increment() {
      this.counter += 5;
    },
  },
};
</script>



보시다시피 스크립트 부분에서 비슷합니다. 상태, 그리고 prop을 전달할 수 있다면 부분을 증가시킬 수 있습니다. 따라서 이 기능을 함수로 추출하지만 원하는 구성 요소를 다시 제공합니다.

HOC(고차 부품)



기존 부분은 이 함수인데 vue 3, the doc link 에서 render 함수와 어떻게 동작하는지 알아야 합니다. 요소를 생성하는 vue 함수인 render 함수의 요약입니다. 그리고 vue는 그것을 뒤에서 사용합니다. 그러나 우리는 vue 컴포넌트에서 템플릿을 사용할 수 있기 때문에 그것에 대해 알 필요가 없습니다. 자바스크립트 파일WithCounter.js을 생성하고 지금은 구성 요소를 전달하고 우리에게 다시 제공하기를 원합니다. 간단합니다. :)

import { h } from "@vue/runtime-core"

function WithCounter(WrappedComponent) {
  // we will return new component that render's WrappedComponent
  return {
    created() {
      console.log('HOC component created')
    },

    render() {
      return h(WrappedComponent)
    }
  }
}

export default WithCounter


이것은 우리의 첫 번째 고차 구성 요소이며 많은 것이 새롭지만 설명하겠습니다. 따라서 먼저 렌더링할 구성 요소를 수락하는 함수가 있습니다. HOC 구성 요소는 렌더링할 구성 요소에 대해 신경 쓰지 않고 다시 사용할 수 있게 만듭니다. 우리의 함수는 객체를 반환할 것이고, 이 객체는 새로운 구성 요소이고, vue의 구성 요소는 스크립트 부분에서 기본 객체를 내보낼 vue 구성 요소의 객체일 뿐입니다. 렌더링이 남아 있으면 맨 위에 가져온 h 함수가 있는 vNode가 생성됩니다. 렌더 기능을 사용하여 사용자 지정 구성 요소를 만들고 싶다면 그렇게 하는 것입니다. 이 고차 구성 요소를 사용하려면 다음을 수행하십시오.

import CounterPlusOne from "./components/CounterPlusOne.vue";
import CounterPlusFive from "./components/CounterPlusFive.vue";
import WithCounter from "./components/WithCounter.js";

export default {
  components: {
    CounterPlusOne: WithCounter(CounterPlusOne),
    CounterPlusFive: WithCounter(CounterPlusFive),
  },
};


지금은 구성 요소와 로그HOC component created를 두 번 렌더링하는 것만으로 많은 작업을 수행하지 않습니다.

재사용 가능한 HOC



이제 카운터 기능을 HOC로 이동합니다. 먼저 간단하게 시작하고 카운터와 함께 인수를 보내면 다음을 의미합니다.

// App.vue
export default {
  components: {
    CounterPlusOne: WithCounter(CounterPlusOne, 1),
    CounterPlusFive: WithCounter(CounterPlusFive, 5),
  },
};

// WithCounter.js
function WithCounter(WrappedComponent, number)


그 기능은 우리가 원하는 만큼 많은 인수를 전달할 수 있기 때문입니다. 이 두 구성 요소의 모든 중복 코드를 WithCounter로 이동할 수 있습니다.


function WithCounter(WrappedComponent, number = 1) {
  return {
    data: () => ({
      counter: 0,
    }),

    methods: {
      increment() {
        this.counter += number;
      },
    },

    render() {
      return h(WrappedComponent, {
        counter: this.counter,
        increment: this.increment
      })
    }
  }
}


내가 말했듯이 증분 방법은 주어진 매개 변수로 리팩토링 될 수 있습니다. 구성 요소에 대한 소품으로 카운터 및 증분만 전달합니다. 그래서 우리의 구성 요소는 다음과 같습니다.

<!-- CounterPlusOne.vue -->
<template>
  <p>counter {{ counter }}</p>
  <button @click="increment">add</button>
</template>

<script>
export default {
  props: {
    counter: Number,
    increment: Function,
  },
};
</script>

<!-- CounterPlusFive.vue -->
<template>
  <p>counter {{ counter }}</p>
  <button @click="increment">add</button>
</template>

<script>
export default {
  props: {
    counter: Number,
    increment: Function,
  },
};
</script>


요약



지금은 완전히 동일하지만 단지 예일 뿐입니다. 양식을 보내고 API에서 데이터를 가져오는 내 tdata 패키지에서 이 패턴을 사용합니다. 나는 이 패턴을 많이 사용하지 않지만 패키지나 타사 라이브러리에 매우 유용하다는 것을 알았습니다.

좋은 웹페이지 즐겨찾기