Vue3全家桶 - Vue3 - 【8】模板引用【ref】(访问模板引用 + v-for中的模板引用 + 组件上的ref)

模板引用【ref

  • Vue3官网-模板引用;
  • 如果我们需要直接访问组件中的底层DOM元素,可使用vue提供特殊的ref属性来访问;

一、 访问模板引用

  • 在视图元素上采用ref属性来设置需要访问的DOM元素:
    • ref 属性可采用 字符串 值的执行设置;
    • ref 属性可采用v-bind::ref的形式来绑定 函数,其函数的第一个参数则为该元素;
  • 如果元素的ref属性值采用的是字符串形式:
    • 在组合式API JS 中,我们需要声明一个同名的ref变量,来获得该模板的引用;
    • 在选项式API JS 中,可通过this.$refs来访问模板的引用;
  • 示例代码:
    • 组合式API:
      <template><!-- 字符串形式的 ref -->账号输入框:<input type="text" ref="account"><button @click="accountInputStyle">改变账号输入框的样式</button><!-- 函数形式的 ref ,必须采用 v-bind 或 : 的形式来给ref绑定属性值 -->密码输入框:<input type="password" :ref="passwordFn"><button @click="passwordInputStyle">改变密码输入框的样式</button>
      </template><script setup>
      import { ref, reactive, computed, onMounted, nextTick } from 'vue'// EXPLAIN 响应式数据
      // ref 变量名 和 对应DOM元素的ref属性值 相等
      let account = ref(null)
      let password = ref(null)// EXPLAIN 函数
      const accountInputStyle = () => {// NOTE 此处设置的 style 均为行内样式account.value.style.padding = '15px'account.value.style.caretColor = 'red'account.value.className = 'rounded'account.value.focus()
      }
      // NOTE 采用函数给ref绑定属性值,该函数的第一个参数为该元素
      // NOTE 在页面渲染的时候会自动执行
      // NOTE 函数式生命的 ref,不会在 this.$refs 中获取
      const passwordFn = (el) => {// el 元素是密码输入框password.value = elconsole.log(password.value)
      }
      const passwordInputStyle = () => {password.value.style.border = '4px solid green'password.value.style.padding = '15px'password.value.focus()
      }onMounted(() => {});
      </script><style scoped>
      .rounded {border: 4px solid purple;
      }
      </style>
      
    • 选项式API:
      <script>
      export default {data: () => ({accountEl: null,passwordEl: null}),methods: {changeAccountInputStyle() {this.accountEl = this.$refs.account // 获取账号输入框的 DOMconsole.log(this.accountEl)this.accountEl.style = "padding: 15px"this.accountEl.className = "rounded"this.accountEl.focus()},passwordRef(el) { this.passwordEl = el  // el 元素是密码输入框},changePasswordInputStyle() {console.log(this.passwordEl) console.log(this.$refs) // 函数式声明的 ref,不会在this.$refs中获取this.passwordEl.style = "padding: 15px"this.passwordEl.className = "rounded"this.passwordEl.focus()},}
      }
      </script><template><!-- ref 字符串值形式 -->账号输入框:<input type="text" ref="account"><button @click="changeAccountInputStyle">改变账号输入框的样式</button><hr><!-- ref 函数形式:元素渲染后,会立即执行该函数 -->密码输入框:<input type="password" :ref="passwordRef"><button @click="changePasswordInputStyle">改变密码输入框的样式</button>
      </template><style>
      .rounded {border-radius: 15px;
      }
      </style>
      

二、 v-for中的模板引用

  • 当在v-for中使用模板引用时:

    • 如果 ref 值是 字符串 形式,在元素被渲染后包含对应整个 列表的所有元素【数组】
    • 如果 ref 值是 函数 形式,则会每渲染一个列表元素就会执行对应的函数【不推荐使用】;
  • 注意:需要 v3.2.25 及以上的版本;

  • 示例代码:

    • 组合式API:
      <script setup>
      import { onMounted, ref } from "vue";// 书本
      let books = ref([{ id: 1, name: "海底两万里" },{ id: 2, name: "骆驼祥子" },{ id: 3, name: "老人与海" },{ id: 4, name: "安徒生童话" },
      ]);let bookList = ref(null);onMounted(() => {console.log(bookList.value); // 获取引用的 DOM 对象,并打印,发现那么是数组,bookList.value[2].className = "error";
      });
      </script><template><ul><li v-for="b in books" :key="b.id" ref="bookList">{{ b.name }}</li></ul>
      </template><style>
      .error {border: 1px solid red;
      }
      </style>
      
    • 选项式API:
      <script>
      export default {data: () => ({books: [{ id: 1, name: "红楼梦" },{ id: 2, name: "三国演义" },{ id: 3, name: "水浒传" },{ id: 4, name: "西游记" },],students: [{ id: 1, name: "Jack" },{ id: 2, name: "Annie" },{ id: 3, name: "Tom" },],}),methods: {changeBookListStyle() {console.log(this.$refs.bookList);this.$refs.bookList[2].style = "color: red";},studentsRef(el) {console.log(el);},},
      };
      </script><template><ul><!-- 如果 ref 值是字符串形式,在元素被渲染后包含对应整个列表的所有元素【数组】 --><li v-for="b in books" :key="b.id" ref="bookList">{{ b.name }}</li></ul><button @click="changeBookListStyle">点我查看 bookList</button><hr /><!-- 如果ref值是函数形式,则会每渲染一个列表元素则会执行对应的函数【不推荐使用】 --><ul><li v-for="s in students" :key="s.id" :ref="studentsRef">{{ s.name }}</li></ul>
      </template>
      
  • 运行效果:

    • 选项式API:
      image.png
    • 组合式API:
      image.png

三、 组件上的ref

  • 模板引用也可以被用在一个子组件上;这种情况下引用中获得的值是组件实例;

    • 如果子组件使用的选项式API,默认情况下父组件可以随意访问该子组件的数据和函数,除非在子组件使用expose选项来暴露特定的数据或函数,expose值为字符串数组;
    • 如果子组件使用的是组合式API<script setup>,那么该子组件默认是私有的,则父组件无法访问该子组件,除非子组件在其中通过defineExpose宏采用对象形式显示暴露特定的数据或函数;
  • 示例代码:

    • 组合式API:
      • 父组件:

        <script setup>
        // NOTE 组合式API中,默认情况下,子组件中的数据、函数等等都是私有的,不能访问
        // NOTE 如果 子组件 通过 defineExpose 宏采用对象形式显式暴露特定的数据或函数等等
        import Vue1 from '@/components/27-组件上的ref - 组合式API/1.vue'
        import { ref, onMounted } from 'vue'
        const login_vue = ref(null)
        const showSonData = () => {console.log(login_vue.value.account)console.log(login_vue.value.password)login_vue.value.toLogin()
        }
        onMounted(() => {});
        </script><template><h3>登录页面</h3><hr><!-- 组件上的 ref 的值为该组件的实例 --><Vue1 ref="login_vue"></Vue1><hr><button @click="showSonData">查看子组件的信息</button>
        </template>
        
      • 子组件:

        <script setup>
        import { ref } from 'vue'
        const account = ref('admin')
        const password = ref('123456')
        const toLogin = () => {alert('登录中……')
        }
        // TODO 采用 defineExpose 将指定数据、函数等等暴露出去
        defineExpose({account,toLogin
        });
        </script><template>账号:<input type="text" v-model="account"><br>密码:<input type="text" v-model="password"><hr><button @click="toLogin">登录</button>
        </template>
        
      • 效果展示:

        • 默认情况下(没有使用defineEpxose):
          image.png
        • 通过defineExpose暴露特定的属性或方法:
          image.png
    • 选项式API:

      • 父组件:
        <script>
        // NOTE 选项式API中,默认情况下,父组件可以随意访问子组件的数据和函数、计算属性等等
        // NOTE 如果 子组件 增加 expose 选项之后,就只能访问 expose 暴露的属性和函数等等
        import Vue1 from '@/components/27-组件上的ref - 选项式API/1.vue'
        export default {name: 'App',components: { Vue1 },data: () => ({login_vue: null}),methods: {showSonData () {console.log(this.login_vue.account)console.log(this.login_vue.password)this.login_vue.toLogin()}},mounted () {// 打印出来的式子组件的ref对象this.login_vue = this.$refs.loginVueconsole.log(this.login_vue)}
        }
        </script><template><h3>登录页面</h3><hr><!-- 组件上的 ref 的值为该组件的实例 --><Vue1 ref="loginVue"></Vue1><hr><button @click="showSonData">查看子组件的信息</button>
        </template>
        
      • 子组件:
        <script>
        export default {name: 'Vue1',data: () => ({account: 'admin',password: '123456'}),methods: {toLogin () {alert('登录中……')}},// TODO 向外暴露属性函数,增加这个选项之后,父组件只能访问该组件暴露的属性或方法等等expose: ['account', 'password']
        }
        </script><template>账号:<input type="text" v-model="account"><br>密码:<input type="text" v-model="password"><hr><button @click="toLogin">登录</button>
        </template><style scoped lang='scss'>
        </style>
        
      • 运行展示:
        • 未增加 expose
          image.png
        • 增加 epxose
          • 子组件没有暴露 toLogin 方法,所以此处访问不了;
            image.png

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蝙蝠避障:我生活中的一道光

盲人的世界&#xff0c;是无尽的黑暗。看不见光&#xff0c;看不见色彩&#xff0c;甚至看不见自己的手。但在这个黑暗的世界里&#xff0c;我找到了一个光明的出口&#xff1a;一款可以障碍物实时检测的名为蝙蝠避障的盲人软件。 这款软件就像是我的一双眼睛。它通过先进的激光…

第五十六回 徐宁教使钩镰枪 宋江大破连环马-飞桨图像分类套件PaddleClas初探

宋江等人学会了钩镰枪&#xff0c;大胜呼延灼。呼延灼损失了很多人马&#xff0c;不敢回京&#xff0c;一个人去青州找慕容知府。一天在路上住店&#xff0c;马被桃花山的人偷走了&#xff0c;于是到了青州&#xff0c;带领官兵去打莲花山。 莲花山的周通打不过呼延灼&#xf…

【日常记录】【工具】随机生成图片的网站 Lorem Picsum

文章目录 1、介绍2、获取固定宽高的图片3、处理图片缓存4、 Emmet 缩写语法 1、介绍 Lorem Picsum 是一个免费的图片占位符服务&#xff0c;可以用于网站、应用程序或任何需要占位符图片的地方。它提供了一个简单的 API&#xff0c;可以通过 HTTP 请求获取随机图片&#xff0c;…

安信可IDE(AiThinker_IDE)编译ESP8266工程方法

0 工具准备 AiThinker_IDE.exe ESP8266工程源码 1 安信可IDE&#xff08;AiThinker_IDE&#xff09;编译ESP8266工程方法 1.1 解压ESP8266工程文件夹 我们这里使用的是NON-OS_SDK&#xff0c;将NON-OS_SDK中的1_UART文件夹解压到工作目录即可 我这里解压到了桌面&#xff0c…

软考73-上午题-【面向对象技术2-UML】-UML中的图4

一、构件图&#xff08;组件图&#xff09; 1-1、构件图的定义 展现了&#xff0c;一组构件之间的组织和依赖。 构件图专注于系统的静态实现图。 构件图与类图相关&#xff0c;通常把构件映射为一个、多个类、接口、协作。 【回顾】&#xff1a; 类图展示了一组对象、接口、…

加速 Webpack 构建:提升效率的秘诀

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

详解DSLS达索许可管理器的安装与配置

DSLS的安装与配置 一、DSLS下载二、安装DLS三、使用DSLS四、更改计算机ID五、部分常见DSLS相关问题 一、DSLS下载 下载地址&#xff1a;https://software.3ds.com/?ticketST-5190987-dUM0dflc6zfjf04F5EXx-cas 注意&#xff1a;需要一个注册了的达索账号才能登录进去下载 一…

内网渗透-跨域环境渗透-1

目录 smbclient工具 mimikatz工具 Kerbers协议 NTLM认证 hash传递攻击&#xff08;PTH攻击&#xff09; 黄金票据攻击 白银票据 MS14-068 smbclient工具 在linux里面连接远程windows共享目录&#xff0c;可以使用这个工具 ​ 第一种连接方式&#xff1a;smbclient -L 目…

git - 笔记

为什么要学习Git 为什么要学习Git软件 为什么学习 因为在主流开发中&#xff0c;基于互联网软件开发的项目都会使用Git软件来进行项目开发过程中的资源管理 比如人力资源 代码资源 比如前端资源 .html .java等代码资源 文档资源 像项目开发中涉及到的需求文档等 这种项目中管理…

在文件夹下快速创建vue项目搭建vue框架详细步骤

一、首先在你的电脑目录下新建一个文件夹 进入该文件夹并打开控制台&#xff08;输入cmd指令&#xff09; 进入控制台后输入 vue create springboot_vue (自己指定名称) 如果出现这类报错如&#xff1a;npm install 的报错npm ERR! network request to http://registry.cnp…

Centos7安装postgresql14步骤

1、进入网址 https://www.postgresql.org/download/ 2、按步骤执行 # Install the repository RPM: sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm# Install PostgreSQL: sudo yum install -y…

蓝桥杯真题讲解:子矩阵(二维滑动窗口)

蓝桥杯真题讲解&#xff1a;子矩阵&#xff08;二维滑动窗口&#xff09; 一、视频讲解二、正解代码 一、视频讲解 蓝桥杯真题讲解&#xff1a;子矩阵&#xff08;二维滑动窗口&#xff09; 二、正解代码 //二维单调队列 #include<bits/stdc.h> #define endl \n #def…

删除数据表

oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 删除数据表属于数据库对象的操作 drop table 表名称; 删除 emp30 表 SQL> drop table emp30;表已删除。 上面这个语句运行后&#xff0c;就会把数据表 emp30 删除 在…

东京工业大学最新!一种具有多周期特征描述的精确ORB提取器

作者&#xff1a;小柠檬 | 来源&#xff1a;3DCV 在公众号「3DCV」后台&#xff0c;回复「原论文」可获取论文pdf 添加微信&#xff1a;dddvision&#xff0c;备注&#xff1a;3D高斯&#xff0c;拉你入群。文末附行业细分群 详细内容请关注3DCV 3D视觉精品课程&#xff1a;…

数据结构 第2章:线性表

文章目录 2.1 线性表的定义和操作2.1.1 线性表的基本概念2.1.2 线性表的基本操作 2.2. 顺序表2.2.1. 顺序表的基本概念2.2.2. 顺序表的实现2.2.3. 顺序表的基本操作 2.3 链表2.3.1 单链表的基本概念2.3.2 单链表的实现2.3.3 单链表的插入2.3.4. 单链表的删除2.3.5. 单链表的查找…

软考69-上午题-【面向对象技术2-UML】-关系

一、关系 UML中有4种关系&#xff1a; 依赖&#xff1b;关联&#xff1b;泛化&#xff1b;实现。 依赖&#xff1a;两个事物之间的语义关系&#xff1b;其中一个事物发生变化会影响另一个事物的语义。 关联&#xff1a;一组对象之间连接的结构关系。 泛化&#xff1a;一般/特…

【libwebrtc】基于m114的构建

libwebrtc A C++ wrapper for binary release, mainly used for flutter-webrtc desktop (windows, linux, embedded).是 基于m114版本的webrtc 最新(20240309 ) 的是m122了。官方给出的构建过程 .gclient 文件 solutions = [{"name" : src,"url

一篇论文回顾 Sora 文生视频技术的背景、技术和应用。

一篇论文回顾 Sora 文生视频技术的背景、技术和应用。 追赶 Sora&#xff0c;成为了很多科技公司当下阶段的新目标。研究者们好奇的是&#xff1a;Sora 是如何被 OpenAI 发掘出来的&#xff1f;未来又有哪些演进和应用方向&#xff1f; Sora 的技术报告披露了一些技术细节&…

docker部署springboot jar包项目

docker部署springboot jar包项目 前提&#xff0c;服务器环境是docker环境&#xff0c;如果服务器没有安装docker&#xff0c;可以先安装docker环境。 各个环境安装docker&#xff1a; Ubuntu上安装Docker&#xff1a; ubuntu离线安装docker: CentOS7离线安装Docker&#xff1…

04-微服务 面试题

目录 1.Spring Cloud 常见的组件有哪些? 2.服务注册和发现是什么意思?(Spring Cloud 如何实现服务注册发现) 3.你们项目负载均衡如何实现的 ? 4.什么是服务雪崩,怎么解决这个问题? 5.你们服务是怎么监控的? 6.微服务限流(漏桶算法、令牌桶算法) 7.解释一下CAP…