首先是API官网关于ref 的解释:
下面用两个例子来深入理解ref和refs
一、ref作用于组件
<div id="app">
<navbar ref="navbar"></navbar>
<input ref="input">
</div>
new Vue({
el:'#app',
mounted:function () {
//访问navbar的navs的footer值
console.log(this.$refs.navbar.navs);
// 这样就允许父级组件通过下面的代码聚焦 <input> 里的输入框:
this.$refs.input.focus()
}
})
通过ref和refs,父组件可以轻松获取子组件的信息
当 ref 和 v-for 一起使用的时候,你得到的引用将会是一个包含了对应数据源的这些子组件的数组。应该避免在模板或计算属性中访问 $refs
二、ref作用于Html标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<p ref="thisP">{{name}}</p></div>
<script>
var vm = new Vue({
data:{
name:'小小陈先森'
}
}).$mount("#app")
// vm.name='Tom';
console.log(vm.$refs.thisP.textContent);
//vm.$nextTick(function () {
// console.log(vm.$refs.thisP.textContent);
//})
</script>
</body>
</html>
上面这个例子可以获取P标签中的文本信息。这样就不需要给P标签设一个id,再document.getElementById('xx),这相当麻烦。
三、$nextTick()
<script>
var vm = new Vue({
data:{
name:'小小陈先森'
}
}).$mount("#app")
vm.name='Tom';
console.log(vm.$refs.thisP.textContent);
vm.$nextTick(function () {
console.log(vm.$refs.thisP.textContent);
})
</script>
控制台显示
看控制台输出,明明给name赋值‘Tom’,为啥还会打印出‘小小陈先森’。name赋值‘Tom’没错,但更新到Dom这个过程是异步的(根本原因是因为Vue中DOM更新是异步的).
Vue 在更新 DOM 时是异步执行的。例如,当你设置 vm.someData = ‘new value’,该组件不会立即重新渲染。当刷新队列时,组件会在下一个事件循环“tick”中更新。
例如,当你设置 vm.someData = ‘new value’,该组件不会立即重新渲染。当刷新队列时,组件会在下一个事件循环“tick”中更新。多数情况我们不需要关心这个过程,但是如果你想基于更新后的 DOM 状态来做点什么,这就可能会有些棘手。虽然 Vue.js 通常鼓励开发人员使用“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们必须要这么做。为了在数据变化之后等待 Vue 完成更新 DOM,可以在数据变化之后立即使用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新完成后被调用。
所以当你打印console.log(vm.$refs.thisP.textContent);时,此时标签的文本内容还是‘小小陈先森’。
但我想获取Dom更新的数据啊,我想获取到的是’Tom’。怎么办?
使用Vue.nextTick()
将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
this.$nextTick(() => {
console.log(vm.$refs.thisP.textContent);
})
本文大部分内容源自知乎链接 https://zhuanlan.zhihu.com/p/50638655, 搬运只是为了方便自己学习。