Vue3 동적 참조

대본



아이콘이 있는 클릭 가능한 필드가 여러 개 있다고 상상해 보십시오. 상위 요소에서 클릭한 위치에 관계없이 입력 필드에 초점을 맞추려고 합니다.

문제



클릭하는 위치에 따라 $event.target가 변경됩니다. 이는 의도한 대상을 찾기 위해 영리한 방법을 사용하거나 우아한 접근 방식을 취해야 함을 의미합니다.

Vue2 솔루션



가장 우아한 접근 방식은 ref를 정의하고 클릭되는 요소에 해당하는 ref에 액세스하는 것입니다.

Vue2에서는 다음과 같이 표시됩니다.

<template>
  <div @click="clickMe('f1')">
    <input ref="f1" />
    <Icon/>
  </div>
  <div @click="clickMe('f2')">
    <input ref="f2" />
    <Icon/>
  </div>
  <div @click="clickMe('f3')">
     <input ref="f3" />
     <Icon/>
  </div>
</template>

<script>
 export default {
   methods: {
     clickMe(refId) {
       var input = this.$refs[refId]
       input?.focus()
     }
   }
 }
</script>



Vue3 문제!



Vue3 컴포지션 API를 사용하는 경우 이 동작을 달성하는 것이 그다지 명확하지 않다는 것을 알 수 있습니다.

메서드는 더 이상 구성 요소에 정의된 모든 참조를 보유하는 개체에 액세스할 수 없습니다. 따라서 덜 우아한 솔루션에 만족하게 될 수 있습니다. 그러나 그럴 필요는 없습니다.

Vue3 솔루션



해결책은 간단합니다. 속성 값이 참조인 개체를 사용합니다. 그런 다음 템플릿을 다음과 같이 업데이트할 수 있습니다.

<script setup>
import { ref } from 'vue';

const inputs = {
    f1: ref(),
    f2: ref(),
    f3: ref(),
}

function clickMe(refId) {
  var input = inputs[refId]?.value
  input?.focus()
}
</script>

<template>
  <div @click="clickMe('f1')">
    <input :ref="inputs.f1" />
    <Icon/>
  </div>
  <div @click="clickMe('f2')">
    <input :ref="inputs.f2" />
    <Icon/>
  </div>
  <div @click="clickMe('f3')">
     <input :ref="inputs.f3" />
     <Icon/>
  </div>
</template>


보너스: Ref를 정의하는 더 나은 방법



심판을 반복해서 쓰는 대신. 배열에서 참조를 정의하는 메서드를 작성할 수 있습니다. Lodash를 사용하고 있기 때문에 이런 식으로했습니다.

function defineRefs(refs) {
  return _.chain(refs).keyBy().mapValues(ref).value();
}


이제 inputs 정의를 다음과 같이 다시 작성할 수 있습니다.

const inputs = defineRefs(['f1', 'f2', 'f3'])


결론



이제 Vue3에서 Vue의 이전 버전과 같은 참조로 가득 찬 객체를 얻는 방법을 알았습니다.

좋은 웹페이지 즐겨찾기