虽然Vue实现了MVVM模型,将数据和表现进行了分离,我们只需要更新数据就能使DOM同步更新,但是某些情况下,还是需要获取DOM元素进行操作(比如引入的某个库要求传入一个根dom元素作为根节点,或者写一些自定义指令),本文主要介绍几种在Vue中获取DOM元素的方法。

使用DOM API直接找元素

  1. <script>
  2. ...
  3. mounted () {
  4. let elm = this.$el.querySelector('#id')
  5. }
  6. </script>

这种方法足够简单直观,Vue组件在patch阶段结束时会把this.$el赋值为挂载的根dom元素,我们可以直接使用$elquerySelector, querySelectorAll等方法获取匹配的元素。

refs

  1. <template>
  2. <div ref="bar">{{ foo }}</div>
  3. <MyAvatar ref="avatar" />
  4. ...
  5. </template>
  6. <script>
  7. ...
  8. mounted () {
  9. let foo = this.$refs['bar'] // 一个dom元素
  10. let avatar = this.$refs['avatar'] // 一个组件实例对象
  11. }
  12. </script>

使用组件实例的$refs即可拿到组件上ref属性对应的元素。

如果ref属性加在一个组件上,那么拿到的是这个组件的实例,否则拿到的就是dom元素了。

值得注意的是包含v-for循环模板指令的情况,其循环元素和子元素上ref属性对应的都是一个数组(就算动态生成ref,也是数组):

  1. <template>
  2. <div v-for="item in qlist" :key="item.id" ref="qitem">
  3. <h3>{{ item.title }}</h3>
  4. <p ref="pinitem">{{ item.desc }}</p>
  5. <p :ref="'contact'+item.id">{{ item.contact }}</p>
  6. </div>
  7. ...
  8. </template>
  9. <script>
  10. ...
  11. data () {
  12. return {
  13. qlist: [
  14. { id: 10032, title: 'abc', desc: 'aadfdcc', contact: 123 },
  15. { id: 11031, title: 'def', desc: '--*--', contact: 856 },
  16. { id: 20332, title: 'ghi', desc: '?/>,<{]', contact: 900 }
  17. ]
  18. }
  19. },
  20. mounted () {
  21. let foo = this.$refs['qitem'] // 一个包含dom元素的数组
  22. let ps = this.$refs['pinitem'] // p元素是v-for的子元素,同样是一个数组
  23. let contact1 = this.$refs['contact' + this.qlist[0].id] // 还是个数组
  24. }
  25. </script>

关于这个的原因,可以从Vue关于ref处理的部分代码得到:

  1. function registerRef (vnode, isRemoval) {
  2. var key = vnode.data.ref;
  3. if (!isDef(key)) { return }
  4. var vm = vnode.context;
  5. // vnode如果有componentInstance表明是一个组件vnode,它的componentInstance属性是其真实的根元素vm
  6. // vnode如果没有componentInstance则不是组件vnode,是实际元素vnode,直接取其根元素
  7. var ref = vnode.componentInstance || vnode.elm;
  8. var refs = vm.$refs;
  9. if (isRemoval) {
  10. ...
  11. } else {
  12. // refInFor是模板编译阶段生成的,它是一个布尔值,为true表明此vnode在v-for中
  13. if (vnode.data.refInFor) {
  14. if (!Array.isArray(refs[key])) {
  15. refs[key] = [ref]; // 就算元素唯一,也会被处理成数组
  16. } else if (refs[key].indexOf(ref) < 0) {
  17. // $flow-disable-line
  18. refs[key].push(ref);
  19. }
  20. } else {
  21. refs[key] = ref;
  22. }
  23. }
  24. }

使用自定义指令

Vue提供了自定义指令,官方文档给出了如下的使用方法,其中el就是dom元素的引用

  1. Vue.directive('focus', {
  2. // 当被绑定的元素插入到 DOM 中时……
  3. inserted: function (el) {
  4. // 聚焦元素
  5. el.focus()
  6. }
  7. })
  8. // 在模板中
  9. <template>
  10. <input v-model="name" v-focus />
  11. </template>

关于自定义指令,在一些组件库和事件上报等场景下非常有用,以后再专门写一篇文章讨论一下吧。

Vue获取DOM的几种方法的更多相关文章

  1. vue获取dom元素高度的方法

    获取高度: <div ref="自定义名称" > </div>要在钩子mounted里面dom结构生成后去获取dom的高度,宽度,修改样式等操作!!! mo ...

  2. javascript获取DOM对象三种方法

    1. getElementByID() getElementByID()方法可返回对拥有指定ID的第一个对象的引用 2. getElementByTagName() getElementByTagNa ...

  3. Vue获取dom和数据监听

    Vue获取dom对象 在js和jq中我们都能获取dom对象例如 // 获取id=1的div标签 <div id=d1>dom对象</div> // js语法 let ele = ...

  4. PHP中获取星期的几种方法

    PHP中获取星期的几种方法   PHP星期几获取代码: 1 date(l); 2 //data就可以获取英文的星期比如Sunday 3 date(w); 4 //这个可以获取数字星期比如123,注意0 ...

  5. VC++获取IDC_EDIT的7种方法

    VC++获取IDC_EDIT的7种方法 http://blog.csdn.net/baizengfei/article/details/7997618 //第一种方法 int number1, num ...

  6. C#获取当前路径的7种方法

    总结C#获取当前路径的7种方法 C#获取当前路径的方法如下: 1. System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName ...

  7. Java获取随机数的几种方法

    Java获取随机数的几种方法 .使用org.apache.commons.lang.RandomStringUtils.randomAlphanumeric()取数字字母随机10位; //取得一个3位 ...

  8. spring 获取 WebApplicationContext的几种方法

    spring 获取 WebApplicationContext的几种方法 使用ContextLoader WebApplicationContext webApplicationContext = C ...

  9. Struts2 后台获取路径的几种方法

    Struts2 后台获取路径的几种方法 package actions.app; import java.io.File; import org.apache.struts2.ServletActio ...

  10. VC获取cookies的几种方法

    方法一: CInternetSession::GetCookie This member function implements the behavior of the Win32 function  ...

随机推荐

  1. 字符串内特殊字符的替换处理,如对\n的替换

    一.对于字符串特殊字符的替换 对于字符串内,\n的处理,如何去掉 s='123,456\n' s1=s.strip('\n') s2=s.replace('\n','') print(s) print ...

  2. windows用curl报错

    https://www.shuzhiduo.com/A/kmzLRmgl5G/ IE浏览器 -> 设置 -> Internet选项 -> 安全 -> 本地Internet -& ...

  3. 调度器42—进程exit退出流程

    基于Linux-5.10 一.do_exit()简要流程 1. 执行路径 各驱动和内核机制中直接调用 SYSCALL_DEFINE1(exit, int, error_code) //exit.c 将 ...

  4. A、创建模式(5种)

    设计模式的分类总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式. ...

  5. Mule获取Http参数

  6. python os.path模块函数功能

    1.os.path.abspath(path) 获取绝对路径,实际上等于os.getcwd()+path 2.os.path.basename(path)取path最后的文件或文件名.如果path以/ ...

  7. SpringBoot导读

    SpringBoot 一.导读 1.开发工具及技术栈 JDK:jdk1.8.0_191 开发工具:IntelliJIDEA 2020.3.2 SpringBoot: 简化Spring的开发 需要一定的 ...

  8. Ubuntu PostgreSQL数据库忘记密码

    1. find / -name pg_hba.conf2. sudo vi /etc/postgresql/13/main/pg_hba.conf 3. 拉到最下面,把postgres所在行的md5改 ...

  9. C# 使用多线程的几种方式

    1.Thread 详细介绍:https://www.cnblogs.com/cheng8/p/16147918.html 使用Thread类通过ThreadStart(无参数)或Parameteriz ...

  10. 关于前端:解决elementUI的对话框Dialog组件点击自动跳转到页面顶部问题

    查看文档寻找解决办法 增加这两个参数即可完满解决 <el-dialog :lock-scroll="false" :append-to-body="true&quo ...