$refs和 $nextTick

思考

1、Vue中如何获取真实DOM元素?
2、还有没有更多方式?


目标

通过id或ref属性获取原生DOM
在mounted生命周期 – 2种方式获取原生DOM标签
1、目标标签 – 添加id / ref
2、恰当时机, 通过id / 通过ref属性 获取目标标签
提示:以下是本篇文章正文内容,下面案例可供参考

一、ref获取原生dom元素

用id属性或者ref属性都可以

<h1 id="h" ref="myH">获取原生dom</h1>
mounted(){ //mounted 生命周期内部
	console.log(document.getElementById("h")); // h1
	console.log(this.$refs.myH); // h1
},

二、ref属性组件对象

1.思考

Vue中能否获取组件对象呢?
通过ref属性获取组件对象
1、创建Demo组件, 写一个方法
2、App.vue使用Demo组件, 给ref属性-名字随意
3、恰当时机, 通过ref属性 获取组件对象, 可调用组件对象里方法等
Demo.vue

<template>
  <div>
      <p>我是Demo组件</p>
  </div>
</template>
<script>
export default {
    methods: {
        fn(){
            console.log("demo组件内的方法被调用了");
        }
    }
}
</script>

More.vue - 获取组件对象 - 调用组件方法

<template>
  <div>
      <p>1. 获取原生DOM元素</p>
      <h1 id="h" ref="myH">我是一个孤独可怜又能吃的小趴菜</h1>
      <p>2. 获取组件对象 - 可调用组件内一切</p>
      <Demo ref="de"></Demo>
  </div>
</template>
<script>
// 目标: 获取组件对象
// 1. 创建组件/引入组件/注册组件/使用组件
// 2. 组件起别名ref
// 3. 恰当时机, 获取组件对象
import Demo from './Child/Demo'
export default {
    mounted(){
        console.log(document.getElementById("h")); // h1
        console.log(this.$refs.myH); // h1

        let demoObj = this.$refs.de;
        demoObj.fn()
    },
    components: {
        Demo
    }
}
</script>

nextTick基础使用

思考:
data数据改变, 马上获取DOM里的内容如何写?

目标:
点击改data,获取原生DOM内容
1、创建标签显示数据
2、点击+1,马上获取原生DOM内容
原因: Vue更新DOM是异步的
目标:等DOM更新后, 触发此方法里函数体执行
1、语法: this.$nextTick(函数体)

<template>
  <div>
      <p>1. 获取原生DOM元素</p>
      <h1 id="h" ref="myH">我是一个孤独可怜又能吃的小趴菜</h1>
      <p>2. 获取组件对象 - 可调用组件内一切</p>
      <Demo ref="de"></Demo>
      <p>3. vue更新DOM是异步的</p>
      <p ref="myP">{{ count }}</p>
      <button @click="btn">点击count+1, 马上提取p标签内容</button>
  </div>
</template>

<script>
// 目标: 获取组件对象
// 1. 创建组件/引入组件/注册组件/使用组件
// 2. 组件起别名ref
// 3. 恰当时机, 获取组件对象
import Demo from './Child/Demo'
export default {
    mounted(){
        console.log(document.getElementById("h")); // h1
        console.log(this.$refs.myH); // h1

        let demoObj = this.$refs.de;
        demoObj.fn()
    },
    components: {
        Demo
    },
    data(){
        return {
            count: 0
        }
    },
    methods: {
        btn(){
            this.count++; // vue监测数据更新, 开启一个DOM更新队列(异步任务)
            console.log(this.$refs.myP.innerHTML); // 0

            // 原因: Vue更新DOM异步
            // 解决: this.$nextTick()
            // 过程: DOM更新完会挨个触发$nextTick里的函数体
             this.$nextTick(() => {
                console.log(this.$refs.myP.innerHTML); // 1
            })
        }
    }
}
</script>

nextTick使用场景

点击按钮自身隐藏, 出现输入框并马上处于激活状态
演示效果

<template>
  <div>
      <input ref="myInp" type="text" placeholder="这是一个输入框" v-if="isShow">
      <button v-else @click="btn">点击我进行搜索</button>
  </div>
</template>

<script>
// 目标: 点按钮(消失) - 输入框出现并聚焦
// 1. 获取到输入框
// 2. 输入框调用事件方法focus()达到聚焦行为
export default {
    data(){
        return {
            isShow: false
        }
    },
    methods: {
        async btn(){
            this.isShow = true;
            // this.$refs.myInp.focus()
            // 原因: data变化更新DOM是异步的
            // 输入框还没有挂载到真实DOM上
            // 解决:
            // this.$nextTick(() => {
            //     this.$refs.myInp.focus()
            // })
            // 扩展: await取代回调函数
            // $nextTick()原地返回Promise对象
            await this.$nextTick()
            this.$refs.myInp.focus()
        }
    }
}
</script>

总结

提示:这里对文章进行总结:

refs: 既可以获取原生DOM,也可以获取组件对象,拿到了之后,进而可以操作他们。
nextTick: Vue中,数据变了,DOM的更新是异步的,当数据变了,想获取的新的DOM,需要在$nextTick(() => { )方法的回调中进行,在回调中,DOM更新完毕。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值