The strongest detailed explanation of VUE $refs and $el

What are $refs and $el? What is the function?  ref, $refs, $el, what is the relationship between the three? Read the latest articles brought to you by this blogger, and explain them to you through a large number of examples. Please bring your smart brain. In the process, I hope you can draw inferences about other cases from one instance.

ref  ( registering reference information for elements or subcomponents is like setting a class for an element if you want to set a style for the element. Similarly, if you want to get the DOM of any element, set a class for the element first ref, in fact, here is similar to the document in JS. Various methods to obtain DOM are similar, but ref is to access the DOM virtualized by VUE, which can effectively reduce performance consumption

Briefly describe the difference between the three:

ref: is the attribute of the element, used to set on the element

$refs: It is a collection of refs, which contains all the refs in the current .vue

Used to get DOM in normal elements and methods/parameters in subcomponents

$el : is used to get the DOM inside the component (including child components, current .vue components, and parent components)

Table of contents

case 1: click the button "OK" to trigger events on other elements

case 2: page loading, get the overall element height in the current .vue file

case 3: parent component, call the method/parameter in the child component (the example here is the page load direct call)

case 4: In what situation/scenario is this.$nextTick(()=>{}) used and what is its function?


case 1: click the button "OK" to trigger events on other elements

<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>
  </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)
},

case 2: page loading, get the overall element height in the current .vue file

mounted(){
    /*
    * 这里通过 this.$el 直接获取当前.vue文件整体 DOM
    */
    console.log(this.$el)
    console.log('我是 当前.vue文件 整体的高度 =>',this.$el.offsetHeight)
    console.log('我是 PassB 我自己的高度 =>',this.$refs.passB.offsetHeight)
},

 Here you can better understand it by comparing class="content" with the cass of the outermost layer of the overall DOM output by the console in the above figure

case 3: parent component, call the method/parameter in the child component (the example here is the page load direct call)

<template>
    <div class="border">
        <div>我是子组件</div>  
        <input v-model="value">
    </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>

case 4: In what situation/scenario is this.$nextTick(()=>{}) used and what is its function?

<template>
  <div class="content">
    <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岁
        })
    }
}

Hey, classmate, it’s not bad, I’ve finished reading all of them, come on!

If you want to see other cases, you can also send me a comment or a private chat!

If the article is helpful to you, add a follower to the blogger and encourage the blogger to create more posts!

Guess you like

Origin blog.csdn.net/weixin_43221910/article/details/123200201