<template> <div class="rain"> <div v-for="(item, index) in 8" :key="index" :ref="el => rain[index] = el" :data-set=" 'data' + index" /> <div ref='single'></div> </div></template><script>import { defineComponent, onMounted,onBeforeUpdate,onUpdated, ref } from 'vue'export default defineComponent({ setup() { const rain = ref([]) const single = ref() onMounted(() => { Console. log('single', single.value) console.log(' loop dom', rain-.value) console.log(' loop DOM first ', rain.value[0]) }) onBeforeUpdate(() => { }) onUpdated(() => { }) return { rain, single } },})</script>Copy the code
The output
Note: best practice vue3**** when using a V-for loop, using ref always retrieves the last element, which must be manually assigned using a function, You can’t use push because it will cause bugs and duplicate elements during updates
= = = = = = >
Vue2 dom operation
<template> <div class="rain"> vue2 <div v-for="(item, index) in 8" :key="index" :ref="`rain-${index}`" :data-set=" 'data' + index" > inner{{ index }} </div> <div ref="single" /> </div></template><script>export default { mounted () { console.log('single', This $refs. Single) console. The log (' circulation fuck dom, enclosing $refs [' rain - 0] [0])}} < / script >Copy the code
The loop in VUe2 consolidates the named ref in an array, causing the inner and outer loop bound ref to be mixed together and become ambiguous
<template> <div class="rain"> vue2 <div v-for="(item, index) in 5" :key="index" ref="rains" :data-set=" 'data' + index" > out{{ index }} <div v-for="(item , index1) in 5" :key="index1" ref="rains" :data-set=" 'data-rains' + index" > inner{{ index1 }} </div> </div> <div ref="single" /> </div></template><script>export default { mounted () { console.log('single', This.$refs.single) console.log(' refs.single ', this.$refs.rains)}}</script>Copy the code
Output result:
Vue3 does not automatically help us to generate the refs array. We can only get the ref of the last element. To match v-for with ref, we need to manually create a variable to accept it, and ref binds a method
<template> <div class="rain"> <div v-for="(item, index) in 8" :key="index" :ref="el => rain[index] = el" :data-set=" 'data-out' + index" > <div v-for="(item, index) in 8" :key="index" :ref="el => rain[index] = el" :data-set=" 'data-in' + index" > inner{{index1}} </div> </div> <div ref='single'></div> </div></template><script>import { defineComponent, onMounted,onBeforeUpdate,onUpdated, ref } from 'vue'export default defineComponent({ setup() { const rain = ref([]) const single = ref() onMounted(() => { Console. log('single', single.value) console.log(' loop dom', rain-.value) console.log(' loop DOM first ', rain.value[6]) }) onBeforeUpdate(() => { }) onUpdated(() => { }) return { rain, single } },})</script>Copy the code
Output result:
Vue3 vs. vue2
1. In Vue 2, the ref attribute used in v-for fills the corresponding $refs property with the REF array. When there are nested V-fors, this behavior becomes ambiguous and inefficient.
2. In Vue 3, this usage will no longer automatically create arrays in $ref. To get multiple Refs from a single binding, bind the ref to a more flexible function (a new feature)