vue3使用自定义hooks获取dom元素的问题说明

 更新时间:2022年04月18日 09:26:54   作者:JDDDDDDyaya  
这篇文章主要介绍了vue3使用自定义hooks获取dom元素的问题说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

使用自定义hooks获取dom元素问题

在自定义hooks的onMounted事件里面 获取ref元素,组件调用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. 传递过来是一个响应式对象
? ? ?*
? ? ?* ?传过来是一个响应式对象,调用这个函数的时候rootRef.value = nul
? ? ?* ?组件实例化完毕,在组件里面 rootRef.value = <div></div>
? ? ?* ?执行 这个onmonted事件,里面就获取到了一个div,这个onMounted事件是当组件实例化完毕才会执行的
? ? ?*/
? ? /**
? ? ?* ?传过来就是一个null
? ? ?* ? onMounted 执行的时候自然也是null
? ? ?*?
? ? ?*/
? ? // ! 感觉是访问同一个地址,如果传递一个响应式对象,然后组件里面给 rootRef.value赋值,这里就也能拿到了
? ? onMounted(() => {
? ? ? ? // debugger
? ? ? ? console.log('hooks slider mounted --->', rootRef)
? ? })
? ? return {}
}```

vue获取/操作组件的dom元素

最近刚做了一个项目,需要用到地图,选择的是腾讯地图,创建地图的时候,需要给地图创建函数中传入地图容器的id或者容器的dom元素,但是在调试过程中,发现怎么都无法获取dom元素,直接通过getElementById也无法获取元素内容。

下面是我的代码内容(非全部内容)

<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>

页面调试的时候,一直报错,无法读取到id的值,直接打印container的值,却是null,但是看了网上其他使用腾讯地图的例子,基本上是一样的思路。

然后就开始找问题,一直折腾,最后才想到是不是因为我把地图容器放到a-modal组件中的原因,然后对比网上的代码,才发现,别人的都是直接放在template中,或者使用其他html元素包裹,而我把地图容器放到了a-modal组件中。

这时就想到,是不是可以通过a-modal组件来获取dom元素,然后就给a-modal组件加上ref属性,代码如下

<a-modal ref="modal">
? ? <div id="map"></div>
</a-modal>

然后打印this.$refs.modal,观察打印的对象,看能不能找到dom元素内容,又想到容器元素被a-modal包裹,相当于使用插槽,所以找到了$slots.default属性,在上面找到了渲染的VNode,终于找到了div#map元素。

既然找到了,那把这个元素传给地图创建函数就行,说做就做,立即改代码。

<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,好了,开始调试。

但是还是有问题,地图有时出来,有时出不来,就想到出不来时,是不是因为div元素还没有渲染出来,既然这样,那就使用vue的$nextTick了,修改open函数:

open(){
? ? this.$nextTick(()=>{
? ? ? ? this.initMap()
? ? })
},

果然,立马没有问题了,无论何时,地图内容都能正常渲染出来。

最后总结

vue中获取/操作页面dom元素,如果元素与template之间都是html标签,可以直接通过document的获取元素方法来获取元素,但是如果之间有自定义组件,则必须通过组件的$slots来获取dom元素,如果有具名插槽,则要根据插槽名称来查找对应插槽下的元素。 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持程序员之家。 

相关文章

  • Vue(定时器)解决mounted不能获取到data中的数据问题

    Vue(定时器)解决mounted不能获取到data中的数据问题

    这篇文章主要介绍了Vue(定时器)解决mounted不能获取到data中的数据问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • Vue生命周期深入分析总结

    Vue生命周期深入分析总结

    Vue的生命周期就是vue实例从创建到销毁的全过程,也就是new?Vue()?开始就是vue生命周期的开始。Vue?实例有?个完整的?命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom?->?渲染、更新?->?渲染、卸载?等?系列过程,称这是Vue的?命周期
    2022-08-08
  • 详解Vue项目中出现Loading chunk {n} failed问题的解决方法

    详解Vue项目中出现Loading chunk {n} failed问题的解决方法

    这篇文章主要介绍了详解Vue项目中出现Loading chunk {n} failed问题的解决方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • Vue封装全局toast组件的完整实例

    Vue封装全局toast组件的完整实例

    组件(Component)是 Vue.js 最强大的功能之一,组件可以扩展 HTML 元素,封装可重用的代码,这篇文章主要给大家介绍了关于Vue封装全局toast组件,需要的朋友可以参考下
    2021-07-07
  • VUE使用axios调用后台API接口的方法

    VUE使用axios调用后台API接口的方法

    这篇文章主要介绍了VUE使用axios调用后台API接口的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-08-08
  • vue  directive定义全局和局部指令及指令简写

    vue directive定义全局和局部指令及指令简写

    这篇文章主要介绍了vue directive定义全局和局部指令及指令简写,本文分步骤给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-11-11
  • vue中实现图片和文件上传的示例代码

    vue中实现图片和文件上传的示例代码

    下面小编就为大家分享一篇在vue中实现图片和文件上传的示例代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • vue实现侧边栏导航效果

    vue实现侧边栏导航效果

    这篇文章主要为大家详细介绍了vue实现侧边栏导航效果,右侧显示对应内容,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • vue3中如何使用Pinia实现数据持久化操作

    vue3中如何使用Pinia实现数据持久化操作

    使用vue3中的pinia,我们可以在多个页面间共享数据,但是一旦我们关闭或刷新页面,这些数据就会丢失,因此,我们需要有一种数据持久化的解决方案,下面我们就来看看具体如何解决的吧
    2023-10-10
  • vue路由--网站导航功能详解

    vue路由--网站导航功能详解

    这篇文章主要介绍了vue路由--网站导航功能详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03

最新评论

?


http://www.vxiaotou.com