vue 组件的数据通信方式很多,本篇着重讲ref/$refs,神助$nextTick。
作用:获取节点或组件实例。
场景:简单的获取节点或组件实例的属性或者方法,但并不改变其数据。
缺陷:必须在模板渲染之后,不是响应式的,时不时配合$nextTick。
ref放在不同的位置,有不同的效果:
- 节点时,可以通过
this.$refs.p得到节点的属性或者方法,如<p ref="p">hello</p> - 组件时,可以通过
this.$refs.child得到相应的组件实例,从而得到组件上面的属性和方法,如<child-component ref="child"></child-component> - v-for语法时,可以通过
this.$refs.items得到节点或组件实例的数组,具体的某项,需要this.$refs.items[index],如<item ref="items" v-for=".">hello</item>
ref要在组件渲染完成之后才能生效
ref 是以属性的方式存在标签上,所以在组件渲染完成之后才会生效。
因此$refs 不是响应式的,避免在模板或计算属性中访问 $refs。
举个例子:
<template lang="pug">
div
list-item(ref="listItem1")
list-item(v-if="isShow" ref="listItem2")
</template>
<script>
import ListItem from "@/components/ListItem";
export default {
components: { ListItem },
data:() => ({ isShow: "" }),
created() {
// 此时模板未渲染
// {}
console.log(1, this.$refs);
},
mounted() {
// 模板已渲染,但isShow是false,所以没有listItem2
// { listItem1:{...} }
console.log(2, this.$refs);
setTimeout(() => {
this.isShow = true;
// 即便这里isShow是true了,但是模板还没更新
// { listItem1:{...} }
console.log(3, this.$refs);
this.$nextTick(() => {
// 只有在模板更新之后
// { listItem1:{...},listItem1:{...} }
console.log(4, this.$refs);
});
}, 500);
}
};
</script>
created的时候,$refs只是一个空对象。mounted的时候,$refs才有数据,但没有渲染的节点或者组件依旧获取不到- 将某个节点或者组件,
v-if的值从false=>true的瞬间,因为模板还未更新,所以依旧获取不到 - 常配合
nextTick