vue3使用自定義hooks獲取dom元素的問題說明
使用自定義hooks獲取dom元素問題
在自定義hooks的onMounted事件里面 獲取ref元素,組件調(diào)用hooks的時候必須要傳遞響應式對象。
分享下樓主自己的觀點
代碼如下
<script>
// demo.vue
import { defineComponent, ref } from 'vue'
import useBars from './useBars'
export default defineComponent({
? ? props: {
? ? ? ? Bars: Array,
? ? },
? ? setup() {
? ? ? ? const rootRef = ref(null)? ? ? ? const { currentPageIndex } = useBars(rootRef) // 這里傳遞過去的是一個響應式對象
?? ??? ?
?? ??? ? const { currentPageIndex: currentPageIndex1 ?} = useBars(rootRef) // 這里傳遞過去的就是一個null,而不是對象
? ? ? ? console.log('組件 setup 最后一段')
? ? ? ? return {
? ? ? ? ? ? rootRef,
? ? ? ? ? ? currentPageIndex,
? ? ? ? }
? ? },
})
</script>// useBar.js
import { onMounted } from 'vue'
export default function useSliders(rootRef) {
?? ?
/**
? ? ?* 1. 傳遞過來是一個響應式對象
? ? ?*
? ? ?* ?傳過來是一個響應式對象,調(diào)用這個函數(shù)的時候rootRef.value = nul
? ? ?* ?組件實例化完畢,在組件里面 rootRef.value = <div></div>
? ? ?* ?執(zhí)行 這個onmonted事件,里面就獲取到了一個div,這個onMounted事件是當組件實例化完畢才會執(zhí)行的
? ? ?*/
? ? /**
? ? ?* ?傳過來就是一個null
? ? ?* ? onMounted 執(zhí)行的時候自然也是null
? ? ?*?
? ? ?*/
? ? // ! 感覺是訪問同一個地址,如果傳遞一個響應式對象,然后組件里面給 rootRef.value賦值,這里就也能拿到了
? ? onMounted(() => {
? ? ? ? // debugger
? ? ? ? console.log('hooks slider mounted --->', rootRef)
? ? })
? ? return {}
}```vue獲取/操作組件的dom元素
最近剛做了一個項目,需要用到地圖,選擇的是騰訊地圖,創(chuàng)建地圖的時候,需要給地圖創(chuàng)建函數(shù)中傳入地圖容器的id或者容器的dom元素,但是在調(diào)試過程中,發(fā)現(xiàn)怎么都無法獲取dom元素,直接通過getElementById也無法獲取元素內(nèi)容。
下面是我的代碼內(nèi)容(非全部內(nèi)容)
<template> <a-modal> ? ? <div id="map"></div> </a-modal> </template>
<script>
import TMap from 'TMap'
export default{
? ? method:{
? ? ? ? open(){
? ? ? ? ? ? this.initMap()
? ? ? ? },
? ? ? ? initMap(){
? ? ? ? ? ? const center = new TMap.LatLng(39.984120,116.307484)
? ? ? ? ? ? const container = document.getElementById('map')
? ? ? ? ? ? const map = new TMap.Map(container, {
? ? ? ? ? ? ? ? center:center,
? ? ? ? ? ? ? ? zoom:11
? ? ? ? ? ? })
? ? ? ? }
? ? }
}
</script>頁面調(diào)試的時候,一直報錯,無法讀取到id的值,直接打印container的值,卻是null,但是看了網(wǎng)上其他使用騰訊地圖的例子,基本上是一樣的思路。
然后就開始找問題,一直折騰,最后才想到是不是因為我把地圖容器放到a-modal組件中的原因,然后對比網(wǎng)上的代碼,才發(fā)現(xiàn),別人的都是直接放在template中,或者使用其他html元素包裹,而我把地圖容器放到了a-modal組件中。
這時就想到,是不是可以通過a-modal組件來獲取dom元素,然后就給a-modal組件加上ref屬性,代碼如下
<a-modal ref="modal"> ? ? <div id="map"></div> </a-modal>
然后打印this.$refs.modal,觀察打印的對象,看能不能找到dom元素內(nèi)容,又想到容器元素被a-modal包裹,相當于使用插槽,所以找到了$slots.default屬性,在上面找到了渲染的VNode,終于找到了div#map元素。
既然找到了,那把這個元素傳給地圖創(chuàng)建函數(shù)就行,說做就做,立即改代碼。
<template> <a-modal ref="modal"> ? ? <div id="map"></div> </a-modal> </template>
<script>
import TMap from 'TMap'
export default{
? ? method:{
? ? ? ? open(){
? ? ? ? ? ? this.initMap()
? ? ? ? },
? ? ? ? initMap(){
? ? ? ? ? ? const center = new TMap.LatLng(39.984120,116.307484)
? ? ? ? ? ? const container = this.$refs.modal.$slots.default[0]
? ? ? ? ? ? const map = new TMap.Map(container, {
? ? ? ? ? ? ? ? center:center,
? ? ? ? ? ? ? ? zoom:11
? ? ? ? ? ? })
? ? ? ? }
? ? }
}
</script>Tip:vue中插槽若沒有名稱,默認是default,所以default[0]就是default插槽中的第一個元素,即我的div#map,好了,開始調(diào)試。
但是還是有問題,地圖有時出來,有時出不來,就想到出不來時,是不是因為div元素還沒有渲染出來,既然這樣,那就使用vue的$nextTick了,修改open函數(shù):
open(){
? ? this.$nextTick(()=>{
? ? ? ? this.initMap()
? ? })
},果然,立馬沒有問題了,無論何時,地圖內(nèi)容都能正常渲染出來。
最后總結(jié)
vue中獲取/操作頁面dom元素,如果元素與template之間都是html標簽,可以直接通過document的獲取元素方法來獲取元素,但是如果之間有自定義組件,則必須通過組件的$slots來獲取dom元素,如果有具名插槽,則要根據(jù)插槽名稱來查找對應插槽下的元素。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue如何實現(xiàn)利用vuex永久儲存數(shù)據(jù)
這篇文章主要介紹了Vue如何實現(xiàn)利用vuex永久儲存數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
vue2利用html2canvas+jspdf動態(tài)生成多頁PDF方式
利用vue2結(jié)合html2canvas和jspdf,可以實現(xiàn)前端頁面內(nèi)容導出為PDF的功能,首先需要安裝相關(guān)依賴,使用html2canvas將指定div內(nèi)容捕捉為圖像,再通過jspdf將圖像轉(zhuǎn)換為PDF2024-09-09

