浅析Ref操作Dom在Vue2.x和Vue3.x的不同

ref操作dom为何既易用又高效?下面本篇文章带大家聊聊ref操作,介绍一下ref获取dom的本质、其在vue2.x和vue3.x的不同等,希望对大家有所帮助!

浅析Ref操作Dom在Vue2.x和Vue3.x的不同

在开发一个项目之前,我们往往都是先做下需求分析,针对前端而言,就是可以调研或者选择一个基础组件库,来提高我们的工作效率。毕竟,对比较计较时间成本的公司来说,不会给你拿看电视剧玩游戏的时间去专门开发一个类似日历的组件。但在市面上的组件库,并不能都能满足我们的需求。这个时候,我们就需要自己手写组件,来应用到项目中。

而这就是我想说的: 如何设计组件,让其既能易于应用(或者说减少代码量),又能提高扩展性,方便需求变更和后续维护?

可以有很多种方式,而利用Ref操作Dom的特性随是其中之一,但这个方式却让我们在维护和操作Modal、Popup以及频繁操作Dom显示和隐藏交互的组件的时候,却发挥得很大优势。【相关推荐:vuejs视频教程、web前端开发】

就对Ref操作Dom的相关知识点以及应用实例分几个方面来做下剖析

立即学习“前端免费学习笔记(深入)”;

Ref获取Dom的本质Ref操作Dom在Vue2.x和Vue3.x的不同Ref操作组件Dom和父子组件单向传递对比

详说

Ref获取Dom的本质

Vue2.x中Vue的对象属性$refs,其实就是所有注册过的ref的一个集合,而ref对应着template模版中,不同组件或普通Dom元素上关联的ref=”xx”; 源码中ref的实际获取方式也是通过原生方式getElementById而得到的Dom节点;可以说ref是document.getElementById的语法糖。vue3的ref延续了vue2的用法,还增加了一个作用就是创建响应式数据

也许有人会问了,既然ref和getElementById都能获取到Dom,那么在项目开发中,我选择哪种方式都没什么区别呢?

关于这个问题,经过数据表明,$refs相对document.getElementById的方法,会减少获取dom节点的消耗;而具体原因,等下一篇文章再详细探讨。

Ref操作Dom在Vue2.x和Vue3.x的不同

Vue2.x

我们只需要在相应的Dom元素或者组件加上ref=”xx”属性,然后在Vue对象中使用this.$refs.xx,就可以直接获取到该Dom并操作其方法属性,

或者
dd

登录后复制

// $refsshowManagerModal () {  this.$refs.avaUserTreeSelect.showModal(this.form.managers)  console.log(this.$refs.user.text)},

登录后复制

Vue3.2

在Vue3.2版本使用的方式

//普通Dom
//组件

登录后复制

import { ref } from 'vue';// modal调整部门弹层Domconst batchAdjustDepartmentRef = ref(null);const user = ref(null);

登录后复制

也许这里有人疑问,为什么声明了一个和template的ref中同名的常量变量就绑定了对应的dom?在这里再补充说明一下:

Vue3 在早期版本( 3.0.0-beta.21 之前)中对 composition api 的支持,只能在组件选项 setup 函数中使用。而相应式的变量都是通过在setup()方法中return {写入需要在模版中使用的变量或方法}

import { defineComponent, ref } from 'vue'export default defineComponent({  name: 'HelloWorld',  setup(props, ctx) {    const count = ref(0)    function add() {      count.value++    }    // 使用return {} 把变量、方法暴露给模板    return {      count,      add,    }  },})

登录后复制在 3.0.0-beta.21 版本中增加了 在 3.2.0 版本中移除

所以在

const user = ref(null);this.$ref.user

Ref操作组件Dom和父子组件单向传递

props父传子,子通过emits传父,这样单方向传递,在控制弹层组件的显示和隐藏方面也可以实现,但是如此一来,我们就会像下面一样父组件

  // 转让管理员组件import ExchangeValidModalVue from './modal/ExchangeValidModal.vue';// modal弹层const visibleExchange = ref(false); // 转让管理员可视化const onExchangeAdmin = () => {  visibleExchange.value = true;};

登录后复制

子组件ExchangeValidModalVue.vue

    const visibleExchange = ref(false);const props = defineProps({  data: {    type: Object,    default: () => {},  },  visible: {    type: Boolean,    default: false,  },});watch(  () => props.visible,  (cur, pre) => {    visibleExchange.value = cur;    if (cur) {      firstTag.value = 1;    }  },);watch(  () => visibleExchange.value,  (cur, pre) => {    emits('update:visible', cur);  },);

登录后复制

从代码里面我们就可以发现通过用父子组件单向传递的方式去实现一个组件的显示和隐藏功能,我们需要如此费劲地声明多个变量,还要做两次监听,万一后面不止一个这样的参数进行传递,那么代码量可想而知,而且也不易维护。

其实显示和隐藏的功能可以直接在内部中进行值的响应即可,并不需要在父级别中操作,如下将上面代码改变一下:

子组件ExchangeValidModalVue.vue

    import { ref } from 'vue';const visible = ref(false);const emits = defineEmits(['call']);const onEmitSelectSuperiod = () => { // 省略  emits('call');};const onOpen = () => {  visible.value = true;};const onClose = () => {  visible.value = false;};defineExpose({  onOpen,  onClose,});

登录后复制

那么在父组件中,我们只需要通过ref得到该组件Dom,然后操作Dom内部的方法即可;

如:父组件改写

  // 转让管理员组件import ExchangeValidModalVue from './modal/ExchangeValidModal.vue';// modal弹层const exchangeRef = ref(null); // 转让管理员可视化const onExchangeOpen = () => {   exchangeRef.onOpen() // 直接操作dom里defineExpose暴露出来的方法};

登录后复制

如此,是不是比父子单向数据传递的方式更加高效易用?当然上面所说的只是我举的一个例子,当后续需要在组件内扩展功能也可按类似的方法代替单向数据流的方式扩展

但,请注意;这种操作dom方式,并不是什么场景下都是最佳的选择;我们可以分情况选择,比如当一些数据只需要在子组件的范畴中实现,而不需要父组件外加干涉的情况下,选择ref操作dom更为高效;

补充知识点:

defineExpose

在 Vue3.2 中,默认不会暴露任何在

Vue3.2 提供了 defineExpose 编译器宏,可以显式地暴露需要暴露的组件中声明的变量和方法

(学习视频分享:vuejs入门教程、vuejs入门教程)

以上就是浅析Ref操作Dom在Vue2.x和Vue3.x的不同的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/3230802.html

(0)
上一篇 2025年4月1日 16:44:05
下一篇 2025年4月1日 16:44:25

AD推荐 黄金广告位招租... 更多推荐

相关推荐

发表回复

登录后才能评论