ref引用DOM元素和组件实例
目标:
能够使用ref
获取页面上DOM或组件的引用:
给元素或组件添加ref="xxx"
的引用名称,通过this.$refs.xxx
获取元素或组件的实例
能够知道
$nextTick
的应用场景并合理地使用:把回调函数里面的代码推迟到当DOM重新渲染完毕之后执行
通过“购物车案例”巩固前4天所有学知识
ref引用 - 引用DOM元素 / 组件实例
Vue的优势:MVVM的数据驱动视图 – 在vue中,程序员不需要操作DOM,只需要把数据维护好即可。
因此,在vue项目中,墙裂不建议安装和使用jQuery,因为没有操作DOM的需求,如果有也是极少的。
什么是ref 引用
ref用来辅助开发者在不依赖于jQuery的情况下且在不调用DOM API的前提下,获取页面上DOM元素或组件的引用。每个vue的组件实例上,都包含一个
$refs
对象,里面存储着对应的DOM元素或组件的引用。默认情况下,组件的$refs
指向一个空对象。打印出vue实例对象this,可以看到,凡是$开头的,都是vue内置的一些成员。
使用ref引用 DOM元素
在标签上通过ref属性来指定一个名字,这个名字就指向这个标签,并添加到$ref
对象中。如:1
<h1 ref="myh1">APP根组件</h1>
1
2
3
4$refs:{//vue实例上的$refs属性值
myh1: h1
}
this.$refs.myh1.style.color = 'red'//操作DOM使用ref引用 组件实例
只要在引用的子组件的标签上,加一个ref,这个名字就指向了这个子组件的vue实例,就可以通过它来调用这个子组件的属性和方法。
建议:只要是ref的引用,尽量都以Ref后缀结尾,这样一看名字就知道是个引用
this.$nextTick
的应用场景
- 问题
在app组件中,控制组件内按钮和输入框元素的切换
1 | <input type="text" v-if="inputVisible" @blur="showButton" ref="iptRef"> |
当我们想要在切换到输入框的时候,直接进入输入框焦点
1 | showinput(){ |
但是this.$refs.iptRef.focus()
这样却报错了TypeError: Cannot read properties of undefined (reading 'focus')
这个错误代表说,我要调用一个focus方法,或我要访问一个focus属性,但是它前面那个东西是undefined
当我们打印console.log(this.$refs.iptRef);
会发现它是undefined
!
- 分析原因
在这个函数中,我们是更改inputVisible的值让文本框显示出来,但是现在页面上文本框还未显示出来,所以拿不到这个元素,因此是undefined
在Vue的生命周期中,当data里面的数据变化,会触发DOM元素的更新,根据最新的数据,重新渲染页面的UI结构。在updated之前,页面还没来得及重新渲染,所以数据是新的,但是页面的结构是旧的。
所以this.inputVisible = true;
这句执行之后,页面上还是按钮,文本框还未被展示,还需要一个更新的过程,需要一定的时间。如果立马去执行this.$refs.iptRef.focus()
是拿不到文本框的
1 | showinput(){ |
总结:this.inputVisible = true
这行代码执行完,只是数据是最新的,页面还没来得及重新渲染,没有文本框,拿不到它的引用,所以是undefined
要想不报错,this.$refs.iptRef.focus()
这一行调用应该放在页面重新渲染完毕之后
- 解决 –
this.$nextTick(cb)
方法
里面接收一个回调,cb是callback
代表:把回调函数里面的代码推迟到当DOM重新渲染完毕之后执行
保证cb回调函数可以操作到最新的DOM元素
1 | showinput(){ |