IT이야기

Vue.js는 v-for 루프 내부 참조

cyworld 2022. 5. 24. 21:57
반응형

Vue.js는 v-for 루프 내부 참조

내부 부품을 사용하려고 했다.v-for을 반복하고 초기화ref부모로부터 이 방법들에 접근하기 위해서입니다.간단한 사례 코드:

<template>
    <div class="hello">
        {{ msg }}
        <ul>
            <list-item 
                v-for="item in items" 
                :key="item.id" 
                :value="item.text" 
                :ref="`item${item.id}`"
            />
        </ul>
    </div>
</template>

<script>
    import ListItem from "./ListItem";
    export default {
        name: "HelloWorld",
        components: {
            ListItem
        },
        data() {
            return {
                msg: "Welcome to Your Vue.js App",
                items: [
                    { id: 1, text: "foo" },
                    { id: 2, text: "bar" },
                    { id: 3, text: "baz" },
                    { id: 4, text: "foobar" }
                ]
            };
        },
        mounted() {
            setTimeout(() => this.$refs.item2.highlight(), 1500);
        }
    };
</script>

그리고ListItem구성 요소:

<template>
    <li v-bind:class="{ highlight: isHighlighted }">
        {{value}}
    </li>
</template>

<script>
    export default {
        name: "list-item",
        props: ["value"],
        data() {
            return {
                isHighlighted: false
            };
        },
        methods: {
            highlight() {
                this.isHighlighted = !this.isHighlighted;
            }
        }
    };
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
    .highlight {
        color: red;
    }
</style>

몇 가지 목록 항목을 렌더링하여 1초 반 후에 한 항목을 강조 표시하면 된다.하지만 오류가 생겼어:Uncaught TypeError: _this.$refs.item2.highlight is not a function
디버그 세션이 끝난 후 흥미로운 사실을 발견했다: 내부에서 정의된 참조v-for루프는 구성요소가 아니라 하나의 구성요소를 가진 배열이다.
논리가 뭐야, f 래퍼는 뭐야?이 사건 만나는 사람 있어?누가 이 행동에 대한 설명을 해줄 수 있을까?
위에 제시된 코드는 다음과 같이 정상 작동한다.setTimeout(() => this.$refs.item2[0].highlight(), 1500);
나는 항상 합격해야 한다.[0]더 나은 방법이 있을까?제발 도와줘.

v-for와 함께 refs를 사용할 때 구성 요소/DOM 노드는 변수 이름에 직접 어레이로 저장되므로 ref 이름에 인덱스 번호를 사용할 필요가 없다.이렇게 할 수 있다.

<list-item
  v-for="item in items" 
  :key="item.id" 
  :value="item.text" 
  ref="items"
/>

구성 요소의 참조를 다음과 같이 사용하십시오.

this.$refs.items[index]

또한 참조가 순서가 아닐 수 있으며 완전히 다른 문제인 다른 방식으로 처리해야 할 수 있다는 점에 유의하십시오.https://github.com/vuejs/vue/issues/4952을 참조하십시오.

Vue 3 사용자의 경우:

Vue 3에서 이러한 사용은 더 이상 자동으로 다음 위치에 어레이를 생성하지 않는다.$refs. 단일 바인딩에서 여러 참조를 검색하려면 바인딩하십시오.ref더 많은 유연성을 제공하는 기능(이것은 새로운 기능):

HTML

<div v-for="item in list" :ref="setItemRef"></div>

옵션 API 사용:

export default {
  data() {
    return {
      itemRefs: []
    }
  },
  methods: {
    setItemRef(el) {
      if (el) {
        this.itemRefs.push(el)
      }
    }
  },
  beforeUpdate() {
    this.itemRefs = []
  },
  updated() {
    console.log(this.itemRefs)
  }
}

Composition API 사용:

import { onBeforeUpdate, onUpdated } from 'vue'

export default {
  setup() {
    let itemRefs = []
    const setItemRef = el => {
      if (el) {
        itemRefs.push(el)
      }
    }
    onBeforeUpdate(() => {
      itemRefs = []
    })
    onUpdated(() => {
      console.log(itemRefs)
    })
    return {
      setItemRef
    }
  }
}

문서 링크: https://v3.vuejs.org/guide/migration/array-refs.html

방법에서 인덱스를 전달하여 v-for 내부의 ref를 처리하려고 했다.

<div v-for="(item, index) in items" @click="toggle(index)">
  <p ref="someRef"></p>
</div>

toggle(index) {
  this.refs['someRef'][index].toggle();
}

그러나 실제로는 참조 지표의 순서가 정해지지 않았기 때문에 잘못된 요소들을 전환하고 있었다.

그래서 데이터 속성을 참조 요소에 추가한 다음 작업을 수행해 보십시오.

<div v-for="(item, index) in items" @click="toggle(index)">
  <p ref="someRef" :data-key="index"></p>
</div>

이제 각 ref는 특정 데이터 키를 가지고 있다.그리고 다음과 같이 토글할 수 있다.

toggle(index) {
  const dropdown = this.$refs['someRef'].find(
        el => el.$attrs['data-key'] === index
    );
  dropdown.toggle();
}

나는 같은 문제에 직면했었다.

소볼본이 말했듯이, 반환가치는$refs.{ref name}v-for ref에 어레이가 있으므로 내 솔루션은$refs.{ref name}기본적으로 하나의 항목만 있는 배열이며, 쓰기$refs.{ref name}[0].methodToCall().

그리고 그것은 내 경우에 효과가 있다.

동적 참조를 사용하여 주문 문제를 해결했다.:ref="'myRef' + index".

이렇게 하면 Vue는 v-for의 각 항목에 대해 새 어레이를 생성하며 이 중 유일한 요소는 항상 원하는 참조가 된다.그러면 다음에 액세스하십시오.this.$refs['myRef' + index][0].

(이것은 Vue 3에서는 작동하지 않을 것이다.)

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.21/vue.js"></script>
<div 
   v-for="(item,index) in items"
   :key="index">
<q-popup-proxy
   ref="qDateProxy">
  <q-date
     :data-key="index"
     v-model="item.date"
     @input="CalendarHide(index)"
     mask="MM/DD/YYYY"
    range>
  </q-date>
</q-popup-proxy>
</div>

<script>
CalendarHide (Val) {
      this.$refs ['qDateProxy'] [val].hide()
}
</script>

Typecript 및 이(vuejs/core#5525) 문제가 있는 Vue 3을 사용하는 모든 사용자에게는 여전히 열려 있다.다른 대답에 기초하여 다음과 같은 일을 할 수 있다.

<div
   v-for="item in items"
   :ref="addRef"
   ...
</div>

...

function addRef(el: unknown) {
  if (el instanceof Element) {
    participantRefs.value.push(el);
  }
}

주요 질문 고려: https://v2.vuejs.org/v2/api/#ref

문서에는 다음과 같은 내용이 수록되어 있다.

ref가 v-for와 함께 사용될 때, 당신이 얻는 ref는 데이터 소스를 미러링하는 하위 구성요소를 포함하는 어레이가 될 것이다.

하지만, 나는 당신이 잘못하고 있다고 말하고 싶다. 왜냐하면,refs좋은 방법이 아니야우리는 에 매우 유용한 대안을 가지고 있다.vue할 수 예를 들어 a를 사용할 수 있다.prop.

이렇게 다시 작성된 코드는 다음과 같이 보일 겁니다.

<template>
    <div class="hello">
        {{ msg }}
        <ul>
            <list-item 
                v-for="item in items" 
                :key="item.id" 
                :value="item.text" 
                :isHighlighed="item.isHighlighed"
            />
        </ul>
    </div>
</template>

<script>
    import ListItem from "./ListItem";
    export default {
        name: "HelloWorld",
        components: {
            ListItem
        },
        data() {
            return {
                msg: "Welcome to Your Vue.js App",
                items: [
                    // We have moved `isHighlighed` falg into the data array:
                    { id: 1, text: "foo", isHighlighed: false },
                    { id: 2, text: "bar", isHighlighed: true },
                    { id: 3, text: "baz", isHighlighed: false },
                    { id: 4, text: "foobar", isHighlighed: false }
                ]
            };
        };
    };
</script>

구성 요소 정의를 변경하여 새 구성 요소 정의 수신prop:

<script>
    export default {
        name: "list-item",
        props: ["value", "isHighlighted"]
    };
</script>

이것으로 너의 문제가 해결될 것이다.

참조URL: https://stackoverflow.com/questions/52086128/vue-js-ref-inside-the-v-for-loop

반응형