$refs 引用
# $refs 引用
# 1. 什么是 ref 引用
ref
用来辅助开发者在不依赖于 jQuery 的情况下,获取 DOM 元素或组件的引用。每个 Vue 的组件实例上,都包含一个 $refs
对象,里面存储着对应的 DOM 元素或组件的引用。默认情况下,组件的 $refs
指向一个空对象。
ref
的语法格式如下:
<!-- 在模板中 -->
<element ref="name"></element>
2
通过在模板中的元素上添加 ref
属性,并指定一个名字,就可以在 Vue 组件实例的 $refs
对象中访问到该元素或组件实例。
使用 `ref` 的典型场景包括:
- 访问子组件的方法和数据:在父组件中直接调用子组件的方法,或访问子组件的数据。
- 操作 DOM 元素:当需要直接操作某个 DOM 元素时,可以通过
ref
获取该元素的引用。 - 与第三方库结合:在某些情况下,可能需要与不遵循 Vue 哲学的第三方库进行整合,此时可以通过
ref
直接操作 DOM。
# 2. 使用 ref 引用 DOM 元素
如果想要使用 ref
引用页面上的 DOM 元素,可以按照如下的方式进行操作:
<template>
<div>
<input type="text" ref="inputElement"> <!-- 在 input 元素上添加 ref="inputElement" -->
</div>
</template>
<script>
export default {
mounted() {
// 在组件挂载后访问 DOM 元素引用
this.$refs.inputElement.focus(); // 让 input 元素获得焦点
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
在上面的示例中,我们在 input
元素上添加了 ref="inputElement"
,然后在 mounted
钩子中通过 this.$refs.inputElement
访问该元素,并调用其 focus
方法,使其获得焦点。
# 3. 使用 ref 引用组件实例
- 如果想要在父组件中直接调用子组件的方法,或访问子组件的数据,可以在子组件或元素上添加
ref
属性。 - 然后在父组件的
mounted
钩子或其他生命周期钩子中,通过this.$refs
获取子组件实例(VueComponent)。
<template>
<div>
<!-- 在自定义组件上使用 ref -->
<child-component ref="childComponent"></child-component> <!-- 在自定义组件上添加 ref="childComponent" -->
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
mounted() {
// 在组件挂载后访问组件实例引用
console.log(this.$refs.childComponent); // 打印子组件实例
this.$refs.childComponent.someMethod(); // 调用子组件的方法
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
在上面的示例中,我们在 child-component
组件上添加了 ref="childComponent"
,然后在 mounted
钩子中通过 this.$refs.childComponent
访问该组件实例,并调用其方法。
# 4. 控制文本框和按钮的按需切换
通过布尔值 inputVisible
来控制组件中的文本框与按钮的按需切换。示例代码如下:
<template>
<div>
<button v-if="!inputVisible" @click="showInput">显示文本框</button> <!-- 当 inputVisible 为 false 时显示按钮 -->
<input v-else type="text" ref="inputElement"> <!-- 当 inputVisible 为 true 时显示文本框 -->
</div>
</template>
<script>
export default {
data() {
return {
inputVisible: false // 控制文本框显示的布尔值,初始值为 false
};
},
methods: {
showInput() {
this.inputVisible = true; // 将 inputVisible 设置为 true,显示文本框
this.$nextTick(() => {
this.$refs.inputElement.focus(); // 在下一个 DOM 更新周期后让文本框获得焦点
});
}
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
在上面的示例中,我们通过 v-if
和 v-else
指令控制文本框和按钮的显示与隐藏。当按钮被点击时,调用 showInput
方法,将 inputVisible
设置为 true
,并使用 $nextTick
在下一个 DOM 更新周期之后让文本框获得焦点。
# 5. 让文本框自动获得焦点
当文本框展示出来之后,如果希望它立即获得焦点,则可以为其添加 ref
引用,并调用原生 DOM 对象的 focus
方法即可。示例代码如下:
<template>
<div>
<button v-if="!inputVisible" @click="showInput">显示文本框</button> <!-- 当 inputVisible 为 false 时显示按钮 -->
<input v-else type="text" ref="inputElement"> <!-- 当 inputVisible 为 true 时显示文本框 -->
</div>
</template>
<script>
export default {
data() {
return {
inputVisible: false // 控制文本框显示的布尔值,初始值为 false
};
},
methods: {
showInput() {
this.inputVisible = true; // 将 inputVisible 设置为 true,显示文本框
this.$nextTick(() => {
this.$refs.inputElement.focus(); // 在下一个 DOM 更新周期后让文本框获得焦点
});
}
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
在上面的示例中,当按钮被点击时,文本框显示出来并自动获得焦点。
# 6. this.$nextTick(callback) 方法
$nextTick
方法用于在下一个 DOM 更新周期之后执行指定的回调函数。这是为了确保对最新的 DOM 结构进行操作,因为 Vue 的 DOM 更新是异步的。语法结构如下:
this.$nextTick(callback);
何时使用
当你在 Vue 组件中更改数据后,可能需要立即对更新后的 DOM 元素进行操作。这时候,$nextTick
就派上用场了。使用 $nextTick
可以确保 DOM 完成更新后,再执行回调函数。
使用场景
- 动态生成的列表:例如,通过 Vue 生成的
list
,希望在生成后立即对 DOM 进行某些操作(如聚焦某个元素)。 - 动画和过渡效果:在数据变更引发的 DOM 更新后执行动画。
- 检测和调试:在数据更新引发 DOM 改变后,验证 DOM 结构。
以下是一个示例,展示如何在更新文本后立即操作最新的 DOM 元素:
<template>
<div>
<button @click="updateText">更新文本</button> <!-- 当按钮被点击时,调用 updateText 方法 -->
<p ref="textElement">{{ text }}</p> <!-- 使用 ref 引用 p 元素 -->
</div>
</template>
<script>
export default {
data() {
return {
text: '初始文本' // 定义初始文本内容
};
},
methods: {
updateText() {
this.text = '更新后的文本'; // 更新文本内容
this.$nextTick(() => {
// 在 DOM 更新完成后操作最新的 DOM 元素
console.log(this.$refs.textElement.innerText); // 输出更新后的文本内容
});
}
}
};
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
注意事项
$nextTick
不适用于所有的场合。若你仅仅是为了在数据更新后执行一些逻辑,而不依赖 DOM 状态的变化,则不必使用$nextTick
。$nextTick
的作用域问题:要确保在组件上下文中调用,以便正确获取到组件实例的refs
和其他实例属性。