vue2.x之ref
ref是用来给元素或组件注册引用信息的。换句话说,就是通过ref我们可以获取元素或组件。
在学习ref之前,我们可以根据document来获取元素的。像这样
<template> <div class="hello"> <h1 id="msg">{{msg}}</h1> </div> </template> <script> export default { name: 'HelloWorld', props: { msg: String }, mounted() { const el = document.querySelector('#msg'); console.log('el', el); } } </script>
效果如下:
举这个例子就是为了引出ref,用ref来获取元素
ref的用法
ref可以用来获取元素和组件。现在来看一下具体的用法
1. ref获取元素
给元素添加一个ref属性
<template> <div class="hello"> <h1 ref="msg">{{msg}}</h1> </div> </template> <script> export default { name: 'HelloWorld', props: { msg: String }, mounted() { console.log(this); } } </script>
效果如下:
👀 从打印信息上可以看出,给元素添加ref属性,可以从组件实例对象上的refs上看到当前ref属性值。那么我们就可以根据这个ref获取到元素了
<template> <div class="hello"> <h1 ref="msg">{{msg}}</h1> </div> </template> <script> export default { name: 'HelloWorld', props: { msg: String }, mounted() { console.log(this.$refs.msg); } } </script>
效果如下:
2. ref获取组件
ref不仅可以获取元素,还可以用来获取组件
⏰ 定义一个子组件
<template> <div class="hi-wrapper"> <h3>你好呀</h3> </div> </template>
<script> export default { name: 'hi' } </script>
⏰ 父组件引入子组件
<template> <div class="hello"> <h1 ref="msg">{{msg}}</h1> <hiFriend ref="hi"></hiFriend> </div> </template> <script> import hiFriend from './hiFriend.vue'; export default { name: 'HelloWorld', components: {hiFriend}, props: { msg: String }, mounted() { console.log(this.$refs.hi); } } </script>
效果如下:
3. ref和v-for一起用
<template> <div class="hello"> <div v-for="(item, index) in arr" :key="index" ref="arr"> <hiFriend ref="msg"></hiFriend> <span ref="item">{{item}}</span> </div> </div> </template> <script> import hiFriend from './hiFriend.vue'; export default { name: 'HelloWorld', components: {hiFriend}, props: { msg: String }, data() { return { arr: [2, 4, 8, 10, 14, 29] } }, mounted() { console.log(this.$refs.arr); console.log(this.$refs.msg); console.log(this.$refs.item); } } </script>
效果如下:
当ref和v-for一起使用的时候,获取到的是元素或者组件实例对象的数组。
小结
1. ref在获取元素上我和document获取元素是一样的,只是在vue中一般不会直接操作DOM, 所以一般还是使用ref获取元素。
2. ref除了可以获取元素之外,还可以获取组件,document是没办法获取组件的。获取到的子组件是一个VueComponent对象
3. ref可以为重复的值,不会报错,但是后面的会覆盖前面的值。
<template> <div class="hello"> <h1 ref="msg">{{msg}}</h1> <hiFriend ref="msg"></hiFriend> </div> </template> <script> import hiFriend from './hiFriend.vue'; export default { name: 'HelloWorld', components: {hiFriend}, props: { msg: String }, mounted() { console.log('父组件', this); console.log('子组件', this.$refs.msg); } } </script>
效果如下:
而且父组件的$refs只有一个值,效果如下:
4. ref只有在mounted阶段才能获取到,而且$refs不是响应式的,因此不能在模板中用作数据绑定