vue中$refs的三种用法解读

 更新时间:2023年01月23日 12:19:40   作者:奇奇怪怪.*  
这篇文章主要介绍了vue中$refs的三种用法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

vue $refs的三种用法

我们都知道,在vue2中获取DOM元素,可以直接在元素上绑定ref属性,然后获取到DOM元素的属性值,这种方法在vue3 中仍然可以使用,但也会有一些问题。

下面就介绍$refs的三种用法:

1、vue2中

在vue2中,我们可以直接使用ref获取元素,也就是直接在元素上绑定ref属性,在直接使用this.$refs[‘自定义属性名’] 就能直接获取。

但是这样也是有一定风险的。因为ref绑定的在元素上,所以当元素没有进行渲染时,是不能通过ref获取到元素的。

<template>
  <div>
    <div ref="btn">我是一个按钮</div>
  </div>
</template>
 
<script>
 
export default {
  name: 'App',
  created() {
    //直接使用this.$refs获取DOM元素
    console.log(this.$refs.btn); // undefined
    this.$nextTick(() => {
        console.log(this.$refs.btn)  //获取到正确元素
    })
  },
  mounted() {
    console.log(this.$refs.btn); //获取到正确元素
  }
}
</script>

需要注意的是,在于vue2中使用这种方法获取v-for的元素时,获取到的是一个数组。

<template>
  <div>
    <div ref="btn" v-for="(item , index) in 3" :key="index">我是一个按钮</div>
  </div>
</template>
 
<script>
 
export default {
  name: 'App',
  mounted() {
    //获取到的是一个元素数组 
    console.log(this.$refs.btn); 
  }
}
</script>

2、vue3中

在一般情况下,vue2的获取元素的方法在vue3也完全适用。

但是,有时候可能会遇到无法获取这个节点,原因是生命周期的问题,在vue3中原来的created没有了,而 setup 充当了原来的 created。

所以在 setup 的时候,dom元素还没有被创建,只有setup完毕了之后HTML才能构建,这时才能真正访问到value值,所以自然就无法获取到dom节点,要想解决这个问题,就要配合钩子函数 onMounted ,在dom挂载完毕后再进行获取。

<template>
    <div id="ref">
        <!--在元素上用 ref="butRef" 绑定-->
        <button type="button" ref="butRef" >按钮元素</button>
    </div>
</template>
 
<script>
    //引入ref
    import {ref, onMounted} from 'vue'
    export default {
        setup() {
 
            //需要先定义butRef
            let butRef = ref(null)
            onMounted(()=>{
              //使用的时候为 butRef.value(需要加点value获取DOM元素值)
              console.log(butRef.value);
            })
            return {
                butRef
            }
        }
    }
</script>

3、vue3的组合API(composition-api)

最后一种方法就是从上下文 Ctx(context)中解构构出 refs,虽然这里refs可能会提示已经被弃用,但是在这里仍然是可以用的。

<template>
    <div id="ref">
        <button type="button" ref="butRef" >按钮元素</button>
    </div>
</template>
 
<script lang="ts">
import { defineComponent, ref, watch } from '@vue/composition-api';
 
export default defineComponent({
    name: '',
    components: {},
    setup (props, ctx) {
        //从Ctx(context)中解构出 refs
        const { emit, refs } = ctx;
            
        watch(filterText, (val) => {
            //在使用的时候直接用 refs.butRef
            //refs.butRef.filter(val);
            (refs.butRef as Any).filter(val);
        });
        return {
            butRef
        }
    }
}
</script>

对vue中$refs的理解

$refs是一个对象,持有注册过ref attribute的所有DOM元素和组件实例。

描述

ref被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的$refs对象上,

如果在普通的DOM元素上使用,引用指向的就是DOM元素;

如果用在子组件上,引用就指向组件实例,

另外当v-for用于元素或组件的时候,引用信息将是包含DOM节点或组件实例的数组。

<!DOCTYPE html>
<html>
<head>
    <title>Vue</title>
</head>
<body>
    <div id="app">
        <div ref="node">Node</div>
        <layout-div ref="layout"></layout-div>
        <div v-for="i in 3" :key="i" ref="nodearr">{{i}}</div>
    </div>
</body>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
<script type="text/javascript">
    Vue.component("layout-div", {
      data: function(){
          return {
            count: 0
          }
      },
      template: `<div>
                    <div>{{count}}</div>
                </div>`
    })
 
    var vm = new Vue({
        el: '#app',
        mounted: function(){
            console.log(this.$refs.node); // <div>Node</div> // DOM元素
            console.log(this.$refs.layout); // VueComponent {_uid: 1, ...} // 组件实例
            console.log(this.$refs.nodearr); // (3) [div, div, div] // DOM元素数组
        }
    })
</script>
</html>

因为ref本身是作为渲染结果被创建的,在初始渲染的时候是不能访问的,因为其还不存在,而且$refs也不是响应式的,因此不应该试图用它在模板中做数据绑定,在初始化访问ref时,应该在其生命周期的mounted方法中调用,在数据更新之后,应该在$nextTick方法中传递回调操作来获取元素或实例,此外一般不推荐直接操作DOM元素,尽量使用数据绑定让MVVM的ViewModel去操作DOM。

<!DOCTYPE html>
<html>
<head>
    <title>Vue</title>
</head>
<body>
    <div id="app"></div>
</body>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
<script type="text/javascript">
 
    var vm = new Vue({
        el: '#app',
        data: function(){
            return {
                msg: 0
            }
        },
        template:  `<div>
                       <div ref="node">{{msg}}</div>
                       <button @click="updateMsg">button</button>
                    </div>`,
        beforeMount: function(){
            console.log(this.$refs.node); // undefined
        },
        mounted: function(){
            console.log(this.$refs.node); // <div>0</div>
        },
        methods: {
            updateMsg: function(){
                this.msg = 1;
                console.log(this.$refs.node.innerHTML); // 0
                this.$nextTick(() => {
                    console.log(this.$refs.node.innerHTML); // 1
                })
            }
        }
    })
</script>
</html>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Vue 进阶教程之v-model详解

    Vue 进阶教程之v-model详解

    这篇文章主要介绍了Vue 进阶教程之v-model详解 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • vue使用exif获取图片旋转,压缩的示例代码

    vue使用exif获取图片旋转,压缩的示例代码

    这篇文章主要介绍了vue使用exif获取图片旋转,压缩的示例代码,帮助大家更好的利用python处理图片,感兴趣的朋友可以了解下
    2020-12-12
  • vue2中Print.js的使用超详细讲解(pdf、html、json、image)

    vue2中Print.js的使用超详细讲解(pdf、html、json、image)

    项目中有用到打印功能,网上就找了print.js,下面这篇文章主要给大家介绍了关于vue2中Print.js使用(pdf、html、json、image)的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-03-03
  • Vue中使用 class 类样式的方法详情

    Vue中使用 class 类样式的方法详情

    这篇文章主要介的是 Vue中如何使用 class 类样式的方法,在vue中为我们提供了几种方式来使用class类的样式,分别是布尔值、表达式、多类封装、下面来看看文章的详细介绍内容吧,需要的朋友可以参考一下
    2021-11-11
  • 详解Vue源码中一些util函数

    详解Vue源码中一些util函数

    这篇文章主要介绍了Vue源码中一些util函数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • vue配置根目录详细步骤(用@代表src目录)

    vue配置根目录详细步骤(用@代表src目录)

    vue用@表示src文件夹,引入时找文件路径更方便,下面这篇文章主要给大家介绍了关于vue配置根目录(用@代表src目录)的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • vue实现购物车的小练习

    vue实现购物车的小练习

    这篇文章主要为大家详细介绍了vue实现购物车的小练习,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • Vue SPA单页面的应用和对比

    Vue SPA单页面的应用和对比

    单页面是指整个应用程序只有一个唯一完整的 HTML 页面,而其它所谓的页面,其实都是组件片段而已,切换页面也只是切换一个 HTML 中显示不同的组件片段。在今后所有的开发项目都是单页面应用
    2022-08-08
  • 详解使用Vue Router导航钩子与Vuex来实现后退状态保存

    详解使用Vue Router导航钩子与Vuex来实现后退状态保存

    本篇文章主要介绍了详解使用Vue Router导航钩子与Vuex来实现后退状态保存,具有一定的参考价值,有兴趣的可以了解一下
    2017-09-09
  • vue项目使用可选链操作符编译报错问题及解决

    vue项目使用可选链操作符编译报错问题及解决

    这篇文章主要介绍了vue项目使用可选链操作符编译报错问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03

最新评论