Vue自定义指令获取DOM元素

我们知道,Vue.js的核心是数据驱动,当数据有所变化时,DOM就会被更新,比如:

<span v-text="msg"></span>
export default {
  data(){
  return{
    msg : ‘oldMsg‘
  }
 }
 methods : {
  changeMsg : function(){
    this.msg = ‘newMsg‘
  }
 }
}

当调用了changeMsg方法,msg被修改为 ‘ newMsg ‘ ,我们可以把这次修改理解为数据发生了变化,此时数据的变化就要驱动DOM变化,我们可以看到<span>oldMsg</span>变成了<span>newMsg</span>,Vue 实现这种响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新,这里涉及到Vue.nextTick 和 vm.$nextTick 等等另外一大堆知识点,我们这里不作深入讨论,我们只需要知道,是数据的变化驱动了DOM的变化,在这个过程中,我们发现我们并没有去操作具体的DOM元素,按照以前的做法,我们可能需要getElementByAnyWays(不论用什么方式获取元素,原生Js或者jQuery.....)获取这个span元素,然后在适当的时候修改它的innerHTML,但我们没有这样做,我们只修改了数据,Vue帮我们实现了DOM的修改与更新,这就是Vue最大的特性之一:数据驱动。

明白了数据驱动这回事,在使用Vue的过程中,我们发现大部分时候不用去操作具体的每个DOM元素,但是,就怕那剩下的小部分时间……我们还是需要获取具体的DOM并且对它做一些事情,当你有这个需求并且去做的时候,你会发现在Vue中获取DOM元素是一件令人头疼的事情。

首先,我们使用一种比较普遍的方法来实现,在需要获取DOM的元素上绑定ref属性,然后通过 this.$refs [ 属性值 ] 来获取。

<p ref="sentence">I‘m waiting for ref</p>
export default{    created(){    console.log(this.$refs.sentence);    // undefined     }   mounted(){    console.log(this.$refs.sentence)    // VueComponent   }}

这里有个小的注意点,就是mounted时期之前,包括beforeMount、created时期,this.$refs都是一个空对象,无法获取到想要的sentence对象,详细解说请戳 官方生命周期图 ,所以,我们要在正确的时间做正确的事情嘛,学习时间就好好看我的文章O(∩_∩)O 。

到了mounted时期,元素已经挂载完成,我们可以获取到sentence对象了,拿到后迫不及待的想要修改它的innerHTML,于是又报错了,this.$refs.sentence.innerHTML是undefined,相当不爽,打断点,一查究竟,发现this.$refs.sentence是奇奇怪怪的VueComponent,并不是我们传统的DOM对象,那怎么获取到我们想要的innerHTML、className等等呢?通过断点仔细查看该VueComponent对象后,发现我们想要的东西都藏在更深一层的属性$el里,如下图:

知道了里面的玄机,我们就可以通过 this.$refs.sentence.$el.innerHTML = "whatever you want" 来修改DOM的内容了。

作了如此多的铺垫,我们是不是可以开始今天高大上的主题了?使用Vue的自定义指令来解决这个问题。

HTML:

<span v-getdom="regist(‘span1‘)"></span>
<p v-getdom="regist(‘p1‘)"></p>

JavaScript:

const vm = new Vue({
  el:‘#app‘,
  data : {
    domEles: {}
  },
  directives : {
    getdom(el, binding) {
      if (typeof binding.value == ‘function‘)
        binding.value(el);
    }
  },
  methods : {
    regist (flag) {
      return (el)=>{
        this.domEles[flag] = el;
      }
    }
  },
  mounted () {
    console.log(this.domEles.span1);  //=> the span DOM Element
    console.log(this.domEles.p1);   //=> the p DOM Element
  }
}) 

首先,我们通过官方提供的directives开发一个局部(局部是指该directives只属于该new Vue()对象,不可被其他Vue对象使用)自定义指令getdom,然后你就可以在模板任何元素上使用v-getdom指令做一些事。

getdom( )传入了两个参数,el 和 binding ,这是官方特定参数,有具体的寓意,如下:

接着,建立一个名为 regist 的方法,接收一个 flag 参数,并根据这个参数返回一个用于将传入参数注册到 this.domEles对象中的闭包函数

将getdom指令与regist方法搭配使用,就可以将想要的元素注册进this.domEles对象中,不论在mounted还是methods中使用都非常方便,只需要this.domEles [ 注册名 ]访问即可,这里我们得到的DOM对象,可以直接获取innerHTML等属性,不需要再深入一层,这与原生DOM是相同的,让我们感到熟悉又舒服。

时间: 2024-10-06 17:02:03

Vue自定义指令获取DOM元素的相关文章

Vue系列之 =&gt; ref获取DOM元素和组件

可以获取DOM元素,和组件中的数据,方法 1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <meta http-eq

Vue获取DOM元素样式 &amp;&amp; 样式更改

在 vue 中用 document 获取 dom 节点进行节点样式更改的时候有可能会出现 'style' is not definde的错误,这时候可以在 mounted 里用 $refs 来获取样式,并进行更改: <template> <div style="display: block;" ref="abc"> <!-- ... --> </div> </template> <script>

vue自定义指令clickoutside使用以及扩展用法

vue自定义指令clickoutside使用以及扩展用法 产品使用vue+element作为前端框架.在功能开发过程中,难免遇到使用element的组件没办法满足特殊的业务需要,需要对其进行定制,例如要求选择器的弹出框中,增加搜索过滤(跟目前element的输入建议不太一样).于是想说说之前修改element组件,并定制为业务组件过程中遇到的问题. ps:因为对某些组件改动很大,所以是直接拷贝了一份源码,然后再进行修改,但是这样会遇到挺多问题,建议对于vue组件如果改动不大,只是简单功能扩展,就

vue自定义指令(Directive中的clickoutside.js)的理解

.array p { counter-increment: longen; margin-left: 10px } .array p::before { content: counter(longen) "." } .alink { font-size: 16px; color: blue } 阅读目录 vue自定义指令clickoutside.js的理解 回到顶部 vue自定义指令clickoutside.js的理解 vue自定义指令请看如下博客: vue自定义指令 一般在需要 DO

vue自定义指令

什么是指令? 指令 (Directives) 是带有 v- 前缀的特殊属性. 它可以写在DOM元素上,对html进行操作.常用的指令比如有:v-if,v-else,v-show,v-for等.这些都是官方直接给定的,另外Vue也允许注册自定义指令,有时这很有用. 自定义指令方法 自定义一个指令很简单,官网给出一个简单的例子,自定义一个聚焦指令v-focus: // 注册一个全局自定义指令 `v-focus` Vue.directive('focus', { // 当被绑定的元素插入到 DOM 中

使用vue自定义指令合并iview表格单元格

使用vue自定义指令合并iview表格单元格, 我们在开发过程中发现iview表格组件,官网只提供了合并表头的demo,并没有合并表格中的单元格. ivew表头分组:https://www.iviewui.com/components/table#BTFZ 效果图如下: 具体实现思路,通过vue自定义属性来操作dom,达到我们想要的效果: 代码如下: demo.vue  表格页面 <template> <div class="demo"><Table :c

通过class和id获取DOM元素的区别

1.通过id获取DOM元素的方法:document.getElementById("id名") 2.通过class获取DOM元素的方法:document.getElementsByClassName("class名") 从函数的名字可以知道,通过getElementsByClassName获取到的是一个数组,包括多个DOM元素,所以要执行DOM元素的方法,必须加一个索引,比如document.getElementsByClassName("class名&q

原生javascript获取dom元素简单介绍

原生javascript获取dom元素简单介绍: 使用jQuery可以各种方式获取元素,比如id选择器,类选择器,元素选择器等等,非常的方便. 下面就介绍一下如何利用原生的js实现获取dom元素的功能. 一.通过id获取元素: 最方便的那就是使用document.getElementById()函数. 具体可以参阅document.getElementById()一章节. 二.通过标签获取元素: 使用document.getElementsByTagName()函数. 具体可以参阅documen

获取DOM元素位置和尺寸大小

JavaScript获取DOM元素位置和尺寸大小 在一些复杂的页面中经常会用JavaScript处理一些DOM元素的动态效果,这种时候我们经常会用到一些元素位置和尺寸的计算,浏览器兼容性问题也是不可忽略的一部分,要想写出预想效果的JavaScript代码,我们需要了解一些基本知识. 基础概念 为了方便理解,我们需要了解几个基础概念,每个HTML元素都有下列属性 offsetWidth clientWidth scrollWidth offsetHeight clientHeight scroll