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.mzph.cn/news/739670.shtml

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

相关文章

PostgreSQL教程(三十九):客户端接口(三)之 信息模式

信息模式由一组视图构成&#xff0c;它们包含定义在当前数据库中对象的信息。信息模式以 SQL 标准定义&#xff0c;因此能够被移植并且保持稳定 — 系统目录则不同&#xff0c;它们是与PostgreSQL相关的并且是为了实现的考虑而建模的。不过&#xff0c;信息模式视图不包含与Pos…

RabbitMQ - 02 - 基本消息模型

目录 部署demo项目 什么是基本消息模型 实现基本消息模型 部署demo项目 首先配置好一个mq的练习demo,并配置好相关依赖 链接&#xff1a;https://pan.baidu.com/s/1oXAqgoz9Y_5V7YxC_rLa-Q?pwdv2sg 提取码&#xff1a;v2sg 如图 父xml文件已经配置好了 AMQP依赖了 什么…

js如何使多个接口串行访问,并行访问

可以使用async/await来保证多个接口串行访问。async/await提供了一种更清晰的方式来写异步代码&#xff0c;它会在等待一个异步操作完成之后再继续执行 async function fn(urls){ for(let i of urls){ let resawait $.fetch(i) } } fn([http://baidu.com,http://baidu.…

计算机408炸了给25考研人的几点警示

25年408考研&#xff0c;如果只用王道的复习资料&#xff0c;最多考100-120分 就是这么的现实&#xff0c;王道的资料虽然好&#xff0c;但是并不能覆盖全部的知识点和考点&#xff0c;而且24年的408真题考的很怪&#xff0c;总结起来就是下面这些特点&#xff1a; 偏&#xff…

安装PyTorch详细过程

安装anaconda 登录anaconda的官网下载&#xff0c;anaconda是一个集成的工具软件不需要我们再次下载。anaconda官网 跳转到这个页面如果你的Python版本正好是3.8版&#xff0c;那便可以直接根据系统去选择自己相应的下载版本就可以了。 但是如果你的Python版本号不是当前页面…

seata入门到实战三

seata datasourceProxy connectionProxy statementProxy和PreparedStatementProxy abstractStatementProxy SqlRecognizer Executor AT模式二阶段提交 一阶段 二阶段提交 全部事务执行成功 释放锁 提交并删除undo日志 二阶段回滚

科普,三分钟读懂高精度NTP时间服务器、时钟服务器

科普&#xff0c;三分钟读懂高精度NTP时间服务器、时钟服务器 科普&#xff0c;三分钟读懂高精度NTP时间服务器、时钟服务器 我们都知道北京时间作为我们国家的标准时间&#xff0c;是由中国科学院国家授时中心产生、保持和发播的。 中国科学院国家授时中心位于陕西西安临潼&…

【LeetCode: 380. O(1) 时间插入、删除和获取随机元素 + 数据结构设计】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【maven下载、安装、配置教程】

一、下载 maven 官网&#xff1a;Maven – Download Apache Maven 注意&#xff1a;idea 和 maven 的版本问题&#xff0c;不然 idea 启动项目会发生兼容性错误。如 2020 版本 idea 支持 3.6.3 左右的 maven 版本&#xff0c;用 3.9版本的 maven 会报错。 二、配置maven全局配置…

JS-06-数组

一、数组的创建与访问 见&#xff1a;JS-04-javaScript数据类型和变量 JavaScript的Array可以包含任意数据类型&#xff0c;并通过索引来访问每个元素。 要取得Array的长度&#xff0c;直接访问length属性&#xff1a; let arr [1, 2, 3.14, Hello, null, true]; console.l…

​LeetCode解法汇总1261. 在受污染的二叉树中查找元素

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给出一个满足下述规则的二叉树&#xff1…

京东商品详情接口数据采集—价格,库存,支持高并发

初识API调用 为帮助商家及开发者快速掌握京东API调用方法&#xff0c;本文为大家提供的万邦API工具为例&#xff0c;为读者演示一例API调用过程&#xff0c;并做相应讲解。 item_get-获得JD商品详情 1、API公共参数示例 请求地址: https://api-gw.onebound.cn/jd/item_get …

【汇编】#2 寄存器相关与实模式下的8086存储器寻址

文章目录 前言一、什么是寄存器二、8086寄存器1. 8086通用寄存器2. 段寄存器3.专用寄存器3.1 标志寄存器内部具体标志及其作用 tips: 不同尺寸数据在存储器中存储 三、 实模式存储器寻址逻辑段与小段物理地址计算方式 前言 本文以清华大学出版社的《80x86汇编语言设计》和李忠…

docker + nginx打包前端镜像

项目场景&#xff1a; 前端使用angular开发&#xff0c;Dockerfile如下&#xff1a; FROM nginx:1.16.1 AS base WORKDIR /app COPY nginx.conf.template /etc/nginx/ CMD ["/bin/bash", "-c", "envsubst ${APP_VERSION} < /app/index.html > …

【CSP考点回顾】后缀表达式计算/中缀表达式转后缀表达式

一、后缀表达式计算 后缀表达式&#xff0c;也被称为逆波兰表示法&#xff08;Reverse Polish Notation&#xff0c;简称RPN&#xff09;&#xff0c;是一种不需要括号来标识操作符优先级的数学表达式。在后缀表达式中&#xff0c;所有的操作符都跟随在它们的操作数之后&#x…

Java 错误 java.net.ConnectException

本篇文章介绍了 Java 中的 java.net.ConnectException 错误。 Java 中的 java.net.ConnectException 错误 java.net.ConnectException 是使用网络时最常见的异常。 它主要发生在客户端、应用程序和服务器之间建立 TCP 连接时。 它是一个经过检查的应用程序,可以使用 try-cat…

day2 员工管理 分类管理

文章目录 新增员工RequestBody方法参数注解 接受json数据两个对象之间属性的拷贝MD5加密 新增员工 DTO 用来接收前端传来的参数 vo用于返回数据 pojo和数据库对应 RequestBody方法参数注解 接受json数据 PostMapping("/")public Result save(RequestBody EmployeeD…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Rating)

提供在给定范围内选择评分的组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Rating(options?: { rating: number, indicator?: boolean }) 从API version 9开始&#…

pinia和vuex区别?

Pinia 和 Vuex 都是用于 Vue.js 应用状态管理的工具&#xff0c;它们有一些明显的区别&#xff1a; 基于 Vue 3 和 Composition API&#xff1a; Pinia 是为 Vue 3 开发的状态管理库&#xff0c;并且充分利用了 Vue 3 的 Composition API。它提供了一种新的、基于函数的状态管理…

C++从零开始(day49)——AVLTree模拟实现

这是关于一个普通双非本科大一学生的C的学习记录贴 在此前&#xff0c;我学了一点点C语言还有简单的数据结构&#xff0c;如果有小伙伴想和我一起学习的&#xff0c;可以私信我交流分享学习资料 那么开启正题 今天分享的是关于AVLTree模拟实现 1.AVLTree概念 二叉搜索树可…