$refs 与 $el是什么? 作用是什么? ref,$refs,$el ,三者之间的关系是什么?
ref (给元素或者子组件注册引用信息) 就像你要给元素设置样式,就需要先给元素设定一个 class 一样,同理,你想获取哪个元素的 DOM,就给这个元素先设定一个 ref,其实这里和 JS 中的 document.各种方法获取 DOM 差不多,不过 ref 是访问 VUE 虚拟出来的DOM,这样可以有效的减少性能消耗。
简述三者区别:
- ref :是 元素的属性,用于设置在元素上
- $refs :是 ref 的集合,集合里面包含了当前.vue中的所有 ref用于获取普通元素中的 DOM 以及 子组件中方法/参数的
- $el :是 用于获取组件内 DOM(包括子组件,当前.vue组件,以及父组件)
1:点击按钮“确定”触发其他元素上的事件
<template>
<div class="content">
<div>
<el-button type="success" @click="handleSubmit">
确定
</el-button>
<!-- 设定 ref="passA" elementui组件按钮-->
<el-button ref="passA" type="success" @click="handlePassA">
被触发 A
</el-button>
</div>
<!-- 设定 ref="passB" 普通按钮触发事件 -->
<div style="height:40px; width:100px; background: burlywood;"
ref="passB" @click="handlePassB">
被触发 B
</div>
</div>
</template>
handleSubmit(){
/*
* 有同学看到这里会问:咦,博主,你这里写法为什么不同呀?
* 嗯,这位同学不错,问到正题上了,避免了你在实际运用中出现问题
* 因为 ref="passA" 的按钮,它是 element ui 提供的组件,
* 组件本身不是 DOM,所以需要 .$el 的帮助后才能提取组件的 DOM
* 反之,对于提取普通元素上的 DOM ,就不需要了
*/
this.$refs.passA.$el.click()
this.$refs.passB.click()
console.log(this.$refs)
},
handlePassA(){
console.log('我是 PassA, 我报触发了')
console.log('我自己的高度 =>',this.$refs.passA.$el.offsetHeight)
},
handlePassB(){
console.log('我是 PassB, 我报触发了')
console.log('我自己的高度 =>',this.$refs.passB.offsetHeight)
},
2.页面加载,获取当前.vue文件中整体元素高度
mounted(){
/*
* 这里通过 this.$el 直接获取当前.vue文件整体 DOM
*/
console.log(this.$el)
console.log('我是 当前.vue文件 整体的高度 =>',this.$el.offsetHeight)
console.log('我是 PassB 我自己的高度 =>',this.$refs.passB.offsetHeight)
},
这里通过 class=“content” 与上图中控制台输出的 整体DOM最外层的 calss 比照,可以更好的理解
3.父组件,调用子组件内的方法/参数(这里的例子是页面加载直接调用)
子组件:
<template>
<div>
<div class="border">
<div>我是子组件</div>
<input v-model="value" />
</div>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
name: 'user-defined',
data() {
return {
value: 0,
list: [1,2,3,4]
}
},
methods: {
handleAddNum(){
console.log('我是子组件里的方法')
this.value = this.value + 1;
// 获取父组件DOM
let parentDom = this.$parent.$el;
}
}
}
</script>
<style scoped lang="scss">
.border{
width: 300px;
height: 200px;
border: 1px solid red;
}
</style>
父组件:
<template>
<div class="content">
<div>
<el-button type="success" @click="handleSubmit">
確定
</el-button>
<!-- 设定 ref="passA" -->
<el-button ref="passA" type="success" @click="handlePassA">
被触发 A
</el-button>
</div>
<!-- 设定 ref="passB" -->
<div style="height:40px; width:100px; background: burlywood;"
ref="passB" @click="handlePassB">
被触发 B
</div>
<!-- 子组件 设定 ref="userDefined" -->
<user-defined ref="userDefined"></user-defined>
</div>
</template>
<script>
import userDefined from './user-defined.vue' // waves directive
import {mapGetters} from 'vuex'
export default {
name: 'AdminPassword',
components: {
userDefined
},
mounted(){
// 调用 子组件方法
this.$refs.userDefined.handleAddNum()
// 调用 子组件list参数
console.log(this.$refs.userDefined.list)
// 输出 $refs 内的集合
console.log(this.$refs)
},
methods: {
handleSubmit(){
this.$refs.passA.$el.click()
this.$refs.passB.click()
console.log(this.$refs)
},
handlePassA(){
console.log('我是 PassA, 我报触发了')
console.log('我自己的高度 =>',this.$refs.passA.$el.offsetHeight)
},
handlePassB(){
console.log('我是 PassB, 我报触发了')
console.log('我自己的高度 =>',this.$refs.passB.offsetHeight)
},
}
}
</script>
4.什么情况/场景中使用 this.$nextTick(()=>{}),它的作用是什么?
<template>
<div class="content">
<!-- elementui中的组件按钮 -->
<el-button type="success" @click="handleSubmit">
获取下方div中文本
</el-button>
<!-- 设定 ref="myDiv" 普通按钮-->
<div ref="myDiv" style="width: 100px; height: 40px; border: 1px solid red;">
{{text}}
</div>
</div>
</template>
data(){
return{
text: '我今年12岁'
}
},
methods: {
handleSubmit(){
/*
* 为什么我打印出来的不是 【我今年13岁】 呢?
* 因为 DOM 的值还没有更新完毕,所以这里打印的依然是【我今年12岁】
*/
this.text = '我今年13岁'
console.log('打印 =>',this.$refs.myDiv.innerHTML) // 打印结果:我今年12岁
}
}
created(){
console.log('created =>',this.$refs.myDiv)
/*
* 因为生命周期执行顺序的缘故,vue 实例刚刚创建完毕 , DOM 还没有进行渲染,所以
* 打印结果:created => undefined
* 如果你在这里输出 this.$refs.myDiv.innerHTML 控制台还会报错,提示 myDiv 不存在
*/
this.$nextTick(()=>{
console.log('created =>',this.$refs.myDiv.innerHTML)
/*
* this.$nextTick 监视 DOM 的更新
* 会进入 红灯停状态,DOM 更新完毕后,就会进入 绿灯行驶状态
* 打印结果:created => 我今年12岁
*/
})
},
methods: {
handleSubmit(){
this.text = '我今年13岁'
/*
* this.$nextTick 的作用是什么?
* 它的作用类似:前方道路正在施工,施工完毕后可正常行驶
* DOM 更新完毕后,就会执行 this.$nextTick 内的代码
*/
this.$nextTick(()=>{
console.log('打印 =>',this.$refs.myDiv.innerHTML) // 打印结果:我今年13岁
})
}
}