vue中ref引用操作DOM元素的实现

 更新时间:2023年01月25日 08:50:36   作者:巧克力小猫猿  
本文主要介绍了vue中ref引用操作DOM元素的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

在javascript中,我们用原生的方式获取页面中的DOM元素,并操作它们。后来,有了jquery,jquery的强大就在于它可以很方便的操作DOM元素。

在vue中,如何操作DOM元素呢?

首先,在vue中强烈禁用原生与jquery来操作DOM元素。我们要充分的利用vue的优势:MVVM,在vue中程序员几乎不操作DOM,只需要维护好数据即可,vue给程序员提供ref引用,不调用api直接获取元素组件的使用

一,$refs对象介绍及基本用法

refs对象的介绍:在每个vue的组件实例上,都包含一个 r e f 对象 = = 存储着对应的 = = D O M 元素 = = 或 = = 组件 = = 的引用, = = 默认情况下,组件的 ref对象==存储着对应的==DOM元素==或==组件==的引用,==默认情况下,组件的 ref对象==存储着对应的==DOM元素==或==组件==的引用,==默认情况下,组件的refs指向一个空对象,凡是以$开头的,都是vue的内置对象

在这里插入图片描述

基础使用方法(获取DOM元素):比如我们要获取h1,则我们给它取一个名字并放入ref中,代码如下:

<h1 ref="myh1">App 根组件</h1>

在引用时,只需在js中:

this.$refs.myh1.style.color = "red";

既可以成功操作:

在这里插入图片描述

我们来看看现在的refs中是不是多了myh1这一个成员:

在这里插入图片描述

总结一下:vue中有一个$refs对象,默认为空。当我们在DOM元素中为其设置ref值后,相当于在vue的内置对象 $refs中添加了新的成员,我们如果需要操作DOM对象直接通过 $refs获取即可。

二,使用ref引用组件实例

ref除了可以引入DOM元素,还可以引入组件。可以拿到组件并操控里面的方法与数据
大家请看left组件结构

<template>
  <div class="left-container">
    <h3>left组件------{{ count }}</h3>
    <button @click="count += 1">+1</button>
    <button @click="resetCount">重置</button>
  </div>
</template>

<script>
export default {
    data() {
        return {
            count: 0
        }
    },
    methods: {
        resetCount() {
            this.count = 0;
        }
    }
}
</script>

<style>
    .left-container {
        height: 200px;
        background-color: orange;
    }
</style>

在我将Left组件导入到App.vue后,我想在App组件中操作Left组件中的元素,比如,我想重置Left组件的count值为0:
首先,与操作DOM元素一样,我要先给Left组件一个ref值:

<Left ref="comLeft"></Left>

在添加ref后,我们再去观察$refs,多了成员comLeft:

在这里插入图片描述

接着,我再设置一个按钮,要求按钮按下后,重置Left组件中的count值为0:

<button @click="onReset">重置Left组件的count值为0</button>

然后设置onReset函数:(用到$refs中的comLeft)

    onReset() {
      this.$refs.comLeft.resetCount();
    }

三,ref的使用案例

3.1 案例需求

案例需求:实现按钮和文本框的按需展示:
有输入框->看不到按钮;
有按钮->看不到输入框。

3.2 思路与做法

首先写出结构,一个输入框与一个按钮。点击按钮时,按钮消失,输入框失去焦点,输入框消失:
通过上述分析,我们可以知道大的方向是要有一个布尔值,默认如果布尔值为false,则默认展示按钮隐藏输入框,否则(true)展示输入框隐藏按钮。

需要用到的知识:
用@click=“”绑定点击事件;v-if与v-show控制元素是否显示(动态的添加与删除元素);使用ref绑定输入框,并使用输入框的focus来控制输入框的焦点。

代码如下:

    <!-- 小demo -->
    <input type="text" v-if="inputVisible" @blur="showButton" ref="iptRef"/>
    <button v-else @click="showInput">展示输入框</button>
  data() {
    return {
      //控制输入框和按钮的按需切换,默认值为false表示默认展示按钮隐藏输入框
      inputVisible: false
    }
  },
  methods: {
    showThis() {
      console.log(this);
      console.log(this.$refs.myh1);
      console.log(this.$refs.comLeft);
      this.$refs.myh1.style.color = "red";
    },
    onReset() {
      console.log(this.$refs);
      this.$refs.comLeft.resetCount();
    },
    showInput() {
      //切换布尔值,把文本框展示出来
      this.inputVisible = true;
      //让展示出来的文本框自动获取焦点
       this.$refs.iptRef.focus();
    },
    showButton() {
      this.inputVisible = false;
    }
  },

请自行编译上述代码会发现问题:虽然showInput提供方法让展示出来的文本框自动获得焦点,但是在页面中却无法实现。

3.2 为什么页面上无法自动获得焦点

因为当布尔值变成true的时候,页面还没来得及更新,这里就跟声明周期有关系了,js是单线程,从上往下渲染,布尔值变成true,还是一个将要展示,还没有展示的状态,所以在页面中渲染不出来:

在这里插入图片描述

解决方法是:保证页面先更新完再执行这个操作,延迟this.$refs.iptRef.focus()的使用在这里插入代码片

如何延迟?我们能不能把这个操作放在updated中?==答案是不能,因为触发updated的条件是,只要数据发生变化就可以触发。所以,当this.inputVisible发生变化,就会触发事件。(updated:数据更新后,完成虚拟DOM的重新渲染和打补丁。组件DOM已完成更新,可执行依赖的DOM操作。注意:不要在此函数中操作数据(修改属性),会陷入死循环)

那么,有什么更好的解决方法呢?

3.3 this.$nextTick(cb)

组件的this.$nextTick(cb)方法,会把cb回调推迟到下一个DOM更新周期之后执行
理解:等组件DOM更新完成后,再执行cb回调函数,从而保证cb回调可操作最新的DOM元素
用法:在括号中(cb回调函数)放入箭头函数并执行操作

    showInput() {
      //切换布尔值,把文本框展示出来
      this.inputVisible = true;
      //让展示出来的文本框自动获取焦点
      // this.$refs.iptRef.focus();
      this.$nextTick(() => {
        this.$refs.iptRef.focus();
      })
    }

3.4 整体代码

<template>
  <div class="app-container">
    <h1 ref="myh1">App 根组件</h1>
    <button @click="showThis">打印 this</button>
    <button @click="onReset">重置Left组件的count值为0</button>
    <hr />

    <!-- 小demo -->
    <input type="text" v-if="inputVisible" @blur="showButton" ref="iptRef"/>
    <button v-else @click="showInput">展示输入框</button>
    <!-- 渲染Left组件 -->
    <div class="box">
      <Left ref="comLeft"></Left>
    </div>
  </div>
</template>

<script>
import Left from "./components/Left.vue";
// console.log($refs);
export default {
  data() {
    return {
      //控制输入框和按钮的按需切换,默认值为false表示默认展示按钮隐藏输入框
      inputVisible: false
    }
  },
  methods: {
    showThis() {
      console.log(this);
      console.log(this.$refs.myh1);
      console.log(this.$refs.comLeft);
      this.$refs.myh1.style.color = "red";
    },
    onReset() {
      console.log(this.$refs);
      this.$refs.comLeft.resetCount();
    },
    showInput() {
      //切换布尔值,把文本框展示出来
      this.inputVisible = true;
      //让展示出来的文本框自动获取焦点
      // this.$refs.iptRef.focus();
      this.$nextTick(() => {
        this.$refs.iptRef.focus();
      })
    },
    showButton() {
      this.inputVisible = false;
    }
  },
  components: {
    Left,
  },
  // updated() {
  //   this.$refs.iptRef.focus();
  // }错误,只要数据变化,就会触发updated
};
</script>

<style>
</style>

四,总结

看完这节知识相信已经学会了如何操作页面中的DOM元素与组件,并知晓了在页面DOM元素更新完后如何操作元素的方法与原理。

到此这篇关于vue中ref引用操作DOM元素的实现的文章就介绍到这了,更多相关vue ref引用操作DOM内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Vue面试题及Vue知识点整理

    Vue面试题及Vue知识点整理

    这篇文章主要介绍了Vue面试题及Vue知识点整理,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧
    2018-10-10
  • Vue滑块验证码组件anji-captcha的使用案例详解

    Vue滑块验证码组件anji-captcha的使用案例详解

    滑块验证是一种常见的人机识别方法,这篇文章主要介绍了Vue滑块验证码组件anji-captcha的使用,本文通过实例代码图文相结合给大家介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • vue如何通过$router.push传参数

    vue如何通过$router.push传参数

    这篇文章主要介绍了vue如何通过$router.push传参数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Elementui按钮设置默认选中状态的实现过程

    Elementui按钮设置默认选中状态的实现过程

    这篇文章主要给大家介绍了关于Elementui按钮设置默认选中状态的实现过程,文中通过图文以及示例代码介绍的非常详细,对大家学习或者使用Elementui具有一定的参考学习价值,需要的朋友可以参考下
    2023-07-07
  • vue2.x中keep-alive源码解析(实例代码)

    vue2.x中keep-alive源码解析(实例代码)

    Keep-Alive模式避免频繁创建、销毁链接,允许多个请求和响应使用同一个HTTP链接,这篇文章主要介绍了vue2.x中keep-alive源码解析,需要的朋友可以参考下
    2023-02-02
  • web前端vue实现插值文本和输出原始html

    web前端vue实现插值文本和输出原始html

    这篇文章主要介绍了web前端vue实现插值文本和输出原始html,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • vue-axios同时请求多个接口 等所有接口全部加载完成再处理操作

    vue-axios同时请求多个接口 等所有接口全部加载完成再处理操作

    这篇文章主要介绍了vue-axios同时请求多个接口 等所有接口全部加载完成再处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • Vue使用xlsx和xlsx-style导出表格出现部分样式缺失的问题解决

    Vue使用xlsx和xlsx-style导出表格出现部分样式缺失的问题解决

    这篇文章主要为大家详细介绍一下Vue使用xlsx-style导出excel时样式的设置,以及出现添加背景色,合并单元格部分样式缺失问题的解决,需要的可以参考下
    2024-01-01
  • 基于Vue实现我的钱包充值功能的示例代码

    基于Vue实现我的钱包充值功能的示例代码

    这篇文章主要为大家详细介绍了如何基于Vue实现我的钱包充值功能,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2024-01-01
  • vue3中$attrs的变化与inheritAttrs的使用详解

    vue3中$attrs的变化与inheritAttrs的使用详解

    $attrs现在包括class和style属性。 也就是说在vue3中$listeners不存在了,vue2中$listeners是单独存在的,在vue3 $attrs包括class和style属性, vue2中 $attrs 不包含class和style属性,这篇文章主要介绍了vue3中$attrs的变化与inheritAttrs的使用 ,需要的朋友可以参考下
    2022-10-10

最新评论