Почему querySelector не работает с v-for?

#javascript #vue.js #vuejs3

Вопрос:

У меня есть простой div v-for цикл, который отображает элементы на странице. На этих элементах есть class надпись, которую я хотел бы выбрать с помощью querySelector метода Javascript.

     <div class="product-feed">
          <div v-for="Product in ProductFeed" :key="Product.ProductID" class="product-item" >
            <Product-Vue-Component :Product="Product"></Product-Vue-Component>
          </div>
    </div>

<script>
...
setup(){
async function loadFeed(){
      await nextTick();
      let element1 = document.querySelector('.product-feed'); 
      console.log(`element1`, element1) // this works and displays the element

      let element2 = document.querySelector('.product-item:last-of-type'); 
      console.log(`element2`, element2) // this comes back as null
      }
    }

   onMounted(()=> {
      loadFeed();
    })
}
...
</script>
 

Несмотря на то , что я жду, когда DOM начнет использовать рендеринг nextTick() , функция loadFeed() не может распознать ни один элемент, находящийся в v-for цикле.

Мне нужно обнаружить элементы в v-for цикле, чтобы я мог реализовать функцию бесконечной прокрутки, в которой загружается больше элементов по мере того, как пользователь прокручивает список .product-item элементов (следовательно :last-of-type , псевдо-селектор)

В чем дело, и можно ли таким образом выбирать элементы?

Комментарии:

1. Все работает в изолированном примере: jsfiddle.net/matvey_andreyev/4qgny59j/2 Вы уверены, что ваша подача продукта доступна в установленное следующее время?

2. @MatveyAndreyev Спасибо за тест, тогда, должно быть, это проблема гонки

Ответ №1:

Попробуйте установить ссылку на div с помощью class="product-item"

 <div ref="el" v-for="Product in ProductFeed" :key="Product.ProductID" class="product-item" >
 

затем в функции настройки :

 const el = ref(null)

onMounted(() => {
    loadFeed()
  })

async function loadFeed(){
  await nextTick();
    let element1 = document.querySelector('.product-feed'); 
    console.log(`element1`, element1) // this works and displays the element

    console.log(el.value) 
  }
}
return {el}
 

Комментарии:

1. Как бы вы получили последнее .product-item ?

2. Эй, приятель, я проверил, и el.value получает последний элемент

Ответ №2:

Пожалуйста, используйте ссылки для этого, просто добавьте атрибут ref в контейнер ref="productFeed" и получите этот элемент с

 import { ref } from 'vue'
...    
const productFeed = ref(null)
...
return {
    productFeed
}
 

Затем вы можете использовать productFeed.value в качестве переменной, содержащей элемент dom

Комментарии:

1. И для петель используйте это

2. Мне product-item не нужно ProductFeed

3. Для этого я оставил ссылку для вас , напишите :ref="el => { if (el) divs[i] = el }" в своем product-item элементе , создайте переменную для своих элементов const divs = ref([]) , очистите ее при обновлении onBeforeUpdate(() => { divs.value = [] }) и используйте console.log(divs.value) в качестве массива элементов Domel

Ответ №3:

Попробуйте использовать ссылки вот так:

 <div
  v-for="Product in ProductFeed" :ref="`product--${Product.id}`">
</div>