探索 Vue.js 中引用的力量:访问和操作 DOM 元素”

news2024/9/21 18:55:49

0.简介

Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架。它由 Evan You 于 2014 年创建,此后作为构建 Web 应用程序的工具越来越受欢迎。

Vue 的核心特性包括:

  • 反应式数据绑定:Vue 使用反应式系统来跟踪对数据模型的更改并自动更新视图。这意味着当数据模型发生变化时,视图将自动更新以反映这些变化。

  • 组件:Vue 允许您使用可重用的组件构建您的应用程序。每个组件都有自己的模板、数据和方法,这有助于使代码井井有条且易于理解。

  • 路由:Vue 提供了一个内置的路由系统,可以让你轻松处理客户端导航。

  • 指令:Vue 提供了一组指令,例如 v-if、v-for、v-bind,它们允许您以声明方式控制 DOM 的行为。

  • 计算属性:Vue 允许您定义在数据模型更改时自动更新的计算属性。计算属性根据它们的依赖关系进行缓存,因此它们仅在某些依赖关系发生变化时才重新评估。

  • Lifecycle Hooks:Vue 允许您利用组件生命周期中的关键时刻,例如 beforeCreated、created、beforeMount、mounted 等。

总的来说,Vue 的设计侧重于简单性和灵活性,使其易于学习和使用,但功能强大到足以构建复杂的应用程序。

Vue.js 中的 ref 指令允许我们在组件实例中访问 DOM 元素或子组件实例。在模板中使用 ref 指令可以将一个元素或子组件实例绑定到组件实例上。之后我们可以在组件实例中通过 $refs 属性访问这个元素或子组件实例。

前言

在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元素更新完后如何操作元素的方法与原理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/182360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

22年部署之docker学习

以下记录的是&#xff0c;我在学习中的一些学习笔记&#xff0c;这篇笔记是自己学习的学习大杂烩&#xff0c;主要用于记录&#xff0c;方便查找https://hub.docker.com/ 镜像中心Docker 常用命令&#xff1a; docker 运行相关运行&#xff1a; service docker start停止&#…

【三年面试五年模拟】算法工程师的独孤九剑秘籍(前十二式汇总篇)V1版

写在前面 【三年面试五年模拟】栏目专注于分享AI行业中实习/校招/社招维度的必备面积知识点与面试方法&#xff0c;并向着更实战&#xff0c;更真实&#xff0c;更从容的方向不断优化迭代。也欢迎大家提出宝贵的意见或优化ideas&#xff0c;一起交流学习&#x1f4aa; 大家好&a…

ABB机器人系统输入输出信号System Input和Output详解(一)

ABB机器人系统输入输出信号System Input和Output详解 System Input类型: 输入I/O信号可指定具体的系统输入项,比如Start或Motors on。该输入项会在不使用FlexPendant示教器或其它硬件装置的情况下触发一项交由系统处理的系统行动。 可以用一个PLC来触发相应的系统输入项。 注…

Node.js教程笔记(三)express

学习目标 能够使用express.static()快速托管静态资源 能够使用express路由精简项目结构 能够使用常见的express中间件 能够使用express创建API接口 能够在express中启用cors跨域资源共享 目录 初识Express Express路由 Express中间件 使用Express写接口 1、初识Expres…

【通信原理(含matlab程序)】实验三 数字基带信号及其频谱特性

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; 本人持续分享更多关于电子通信专业内容以及嵌入式和单片机的知识&#xff0c;如果大家喜欢&#xff0c;别忘点个赞加个关注哦&#xff0c;让我们一起共同进步~ &#x…

Android OpenCV(二)主体识别 位置检测

前言 工作中遇到需要通过OpenCV找到图片主体体积占图片百分比的比例&#xff0c;这里做一个问题解决思路的记录。该方面新手小白&#xff0c;有不对的地方可以评论指出哈 。 重要API Sobel算法 Sobel 计算参考文章 索贝尔算子是计算机视觉领域的一种重要处理方法。 主要用于…

内网传输——解决物联网信息安全和隐私保护问题

与普通电脑系统不同&#xff0c;物联网建立在嵌入式系统的基础之上&#xff0c;其通信协议因设备和应用程序而异。目前还没有一个统一的中央系统来构建安全措施&#xff0c;那么&#xff0c;在企业物联网实际应用中&#xff0c;如何保证信息安全&#xff1f;物联网生态系统的安…

OpenHarmony社区运营报告(2022年12月)

本月快讯• 本月新增22款产品通过兼容性测评&#xff0c;累计220款产品通过兼容性测评。• 12月28日&#xff0c;OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;凭借其创新的技术特性和开源生态建设成果&#xff0c;荣膺“InfoQ 2022年度十大开源新锐项…

Redis实现用户签到 | 黑马点评

目录 一、BitMap用法 1、介绍 2、用法 3、练习 二、签到功能 1、需求 2、代码实现 三、签到统计 1、分析 2、接口实现 一、BitMap用法 1、介绍 我们完全可以通过数据库签到表来实现签到功能&#xff0c;但是假如我们的用户达到千万&#xff0c;每年平均签到10次&am…

基于微信小程序的网络安全科普系统小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.…

设计模式之简单工厂

现在有一个这样的需求&#xff1a;控制台输入俩个数&#xff0c;并输入运算符&#xff0c;计算并输出结果。上述需求乍一看&#xff0c;特别像一个小型的计算器&#xff0c;记得初学Java时&#xff0c;实现过。 实现一&#xff1a; 创建计算器类&#xff0c;控制台输入俩个数…

windows 10 本地配置Oracle19+用navicat连接

文章目录0.背景环境0.背景知识1.卸载旧版本、安装 oracle 192.配置3.用 Navicat 连接3.1 下载instantclient193.2 配置dll使能连接高版本oracle3.3 配置连接4. 相关操作命令5.本地命令行登录orclpdb下的用户0.背景环境 本机已安装oracle12和Navicat15&#xff0c;需要先彻底卸载…

【docker】基础知识梳理与使用

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 docker基础知识的梳理与使用 1. docker的理解 Registry&#xff08;仓库&#xff09;&#xff1a;是一个集中存储与分发镜像的服务。最常用的Registry是…

油井远程监控解决方案

1.项目背景 油田生产过程中&#xff0c;由于井筒内存在着不同程度的缺陷&#xff0c;会产生各种问题。而油井开采设备的连续稳定运行是保证石油开采的首要条件&#xff0c;但是由于油田地域广阔&#xff0c;油井分布广泛&#xff0c;没有规则性的油井工作状况的监测和控制&…

Acwing4655. 重新排序(差分模板题)

给定一个数组 A 和一些查询 Li,Ri&#xff0c;求数组中第 Li 至第 Ri 个元素之和。 小蓝觉得这个问题很无聊&#xff0c;于是他想重新排列一下数组&#xff0c;使得最终每个查询结果的和尽可能地大。 小蓝想知道相比原数组&#xff0c;所有查询结果的总和最多可以增加多少? …

【树】二叉树的非递归遍历

非递归的遍历需要使用栈保存当前不输出的结点&#xff0c;并且三种遍历顺序步骤有所不同。中序遍历1.查看其当前结点是否为空&#xff1a;若非空则将当前结点入栈&#xff0c;指针指向其左孩子&#xff1b;若当前结点为空&#xff0c;说明上一个入栈的结点没有左孩子&#xff0…

vite+vue3+elementPlus搭建项目

创建基础框架 方式一&#xff1a; 创建命令 npm create vitelatest or yarn create vite 注意&#xff1a;这里可能会出现一个坑&#xff0c;注意你的node版本&#xff08;node版本过低就会报错&#xff09; 创建成功 创建成功后运行以下命令即可 yarn yarn dev 这种创建方…

C技能树-判断语句

三个数从小到大排序并输出 任意输入3个整数&#xff0c;使用if语句对这3个整数由小到大进行升序排序。请判断下面哪一项无法实现该功能。 #include <stdio.h>/* 交换x和y */ void swap(int* x, int* y) {int temp *x;*x *y;*y temp; }int main(int argc, char** arg…

[红明谷CTF 2021]write_shell

目录 信息收集 payload 补充知识 信息收集 代码审计 <?php error_reporting(0); highlight_file(__FILE__); function check($input){if(preg_match("/| |_|php|;|~|\\^|\\|eval|{|}/i",$input)){// if(preg_match("/| |_||php/",$input)){die(h…

(二十七)Map集合体系

目录 前言: 一、Map集合的遍历方式之一:键找值 二、Map集合的遍历方式之二:键值对 三、Map集合的遍历方式之三:Lambda表达式 四、Map集合的实现类HashMap 五、Map集合的实现类LinkedHashMap 六、Map集合的实现类TreeMap 七、不可变集合 前言: ①Map集合是一种双列集合&a…