vue中document.querySelector/this.$el.querySelector/ref获取DOM的区别

616 阅读1分钟

一、使用document.querySelector获取DOM

Parent.vue

<template>
  <div class="parent">
    <div class="box">parent-box</div>
    <Child />
  </div>
</template>
<script>
import Child from './Child.vue'
export default {
  created () {
    this.$nextTick(() => {
      const parentBox = document.querySelector('.box')
      console.log(parentBox)
    })
  },
  components: { Child }
}
</script>

Child.vue

<template>
  <div class="child">
    <div class="box">child-box</div>
  </div>
</template>
<script>
export default {
  created () {
    this.$nextTick(() => {
      const childBox = document.querySelector('.box')
      console.log(childBox)
    })
  }
}
</script>

请注意,Child组件中获取的box是Parent组件中的DOM image.png

此时,App组件中若也有一个div设置了box类名,就会这样: image.png

所以,vue不推荐使用这种方式获取DOM

二、使用this.$el.querySelector获取DOM

现在,将Parent和Child组件中获取DOM的方式都改为this.$el.querySelector

      const parentBox = this.$el.querySelector('.box')



      const childBox = this.$el.querySelector('.box')

这样看好像也没什么问题 image.png

但是,如果在Parent组件中将DOM的顺序变换一下:

  <div class="parent">
    <Child />
    <div class="box">parent-box</div>
  </div>

此时,Parent组件中获取到的将是Child组件中的box,这显然和初衷不一样,这也是一部分代码难以维护的原因。。。 image.png

三、使用ref获取DOM

  <div class="parent">
    <div class="box" ref="boxRef">parent-box</div>
    <Child />
  </div>
  
  
        const parentBox = this.$refs.boxRef
  <div class="child">
    <div class="box" ref="boxRef">child-box</div>
  </div>
  
  
        const childBox = this.$refs.boxRef

这是vue推荐的获取DOM的方式,只能获取本组件中的DOM image.png

四、总结

  1. 能用ref就不要用其他方式获取DOM
  2. 如果要用document.querySelector,一定要确保该类名是唯一的
  3. 使用this.$el.querySelector的前提是子组件中最好不要有相同的类名,或者当前DOM的排序在子组件前面