Vue自定义指令获取DOM元素

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

<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

 

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

 

首先,咱们使用一种比较广泛的方法来实现,在须要获取DOM的元素上绑定ref属性,而后经过 this.$refs [ 属性值 ] 来获取。app

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

到了mounted时期,元素已经挂载完成,咱们能够获取到sentence对象了,拿到后火烧眉毛的想要修改它的innerHTML,因而又报错了,this.$refs.sentence.innerHTML是undefined,至关不爽,打断点,一查究竟,发现this.$refs.sentence是奇奇怪怪的VueComponent,并非咱们传统的DOM对象,那怎么获取到咱们想要的innerHTML、className等等呢?经过断点仔细查看该VueComponent对象后,发现咱们想要的东西都藏在更深一层的属性$el里,以下图:ide

 

知道了里面的玄机,咱们就能够经过 this.$refs.sentence.$el.innerHTML = "whatever you want" 来修改DOM的内容了。函数

 

 

做了如此多的铺垫,咱们是否是能够开始今天高大上的主题了?使用Vue的自定义指令来解决这个问题。学习

HTML:ui

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

JavaScript:this

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是相同的,让咱们感到熟悉又舒服。

相关文章
相关标签/搜索