Vue 实例中使用$refs的注意事项

在开发过程中,经常会通过实例的vm.$refs(this.$refs)取得通过ref注册过的组件,并进行相应操作,但存在取不到元素的情况,其根本原因是因为$refs只能取得mounted(渲染)之后的元素。

例如,在这种情况中,若flag从真值切换到假值取不到节点是正常的,因为v-if如果为假值,那么该节点不会被渲染。

但如果从假值切换到真值时,也可能取不到节点,这是因为渲染需要时间,通常可以使用$nextTick()解决。

...
<el-table v-if="flag" ref="table">
  <el-table-column prop="prop1"></el-table-column>
  <el-table-column prop="prop2"></el-table-column>
</el-table>
...

export default {
  methods: {
    this.$refs.table.XXX()
  }
}

但存在一个极特殊的情况,第一次页面渲染的时候,$refs也取不到值。这个时候就要考虑v-show进行组件元素的隐藏与展示。

因为v-show是通过css的display:none进行隐藏控制,所以一开始就会渲染,肯定能够取到元素

补充:Vue.js中ref ($refs)用法举例总结及应注意的坑

一、根据官方文档总结的用法:

看Vue.js文档中的ref部分,自己总结了下ref的使用方法以便后面查阅。

1、ref使用在外面的组件上

HTML 部分

<div id="ref-outside-component" v-on:click="consoleRef">
  <component-father ref="outsideComponentRef">
  </component-father>
  <p>ref在外面的组件上</p>
</div>

js部分

var refoutsidecomponentTem={
    template:"<div class='childComp'><h5>我是子组件</h5></div>"
  };
  var refoutsidecomponent=new Vue({
    el:"#ref-outside-component",
    components:{
      "component-father":refoutsidecomponentTem
    },
    methods:{
      consoleRef:function () {
        console.log(this); // #ref-outside-component   vue实例
        console.log(this.$refs.outsideComponentRef); // div.childComp vue实例
      }
    }
  });

2、ref使用在外面的元素上

HTML部分

<!--ref在外面的元素上-->
<div id="ref-outside-dom" v-on:click="consoleRef" >
  <component-father>
  </component-father>
  <p ref="outsideDomRef">ref在外面的元素上</p>
</div>

JS部分

var refoutsidedomTem={
    template:"<div class='childComp'><h5>我是子组件</h5></div>"
  };
  var refoutsidedom=new Vue({
    el:"#ref-outside-dom",
    components:{
      "component-father":refoutsidedomTem
    },
    methods:{
      consoleRef:function () {
        console.log(this); // #ref-outside-dom  vue实例
        console.log(this.$refs.outsideDomRef); //  <p> ref在外面的元素上</p>
      }
    }
  });

3、ref使用在里面的元素上---局部注册组件

HTML部分

<!--ref在里面的元素上-->
<div id="ref-inside-dom">
  <component-father>
  </component-father>
  <p>ref在里面的元素上</p>
</div>

JS部分

  var refinsidedomTem={
    template:"<div class='childComp' v-on:click='consoleRef'>" +
            "<h5 ref='insideDomRef'>我是子组件</h5>" +
         "</div>",
    methods:{
      consoleRef:function () {
        console.log(this); // div.childComp  vue实例
        console.log(this.$refs.insideDomRef); // <h5 >我是子组件</h5>
      }
    }
  };
  var refinsidedom=new Vue({
    el:"#ref-inside-dom",
    components:{
      "component-father":refinsidedomTem
    }
  });

4、ref使用在里面的元素上---全局注册组件

HTML部分

<!--ref在里面的元素上--全局注册-->
<div id="ref-inside-dom-all">
  <ref-inside-dom-quanjv></ref-inside-dom-quanjv>
</div>

JS部分

  Vue.component("ref-inside-dom-quanjv",{
    template:"<div class='insideFather'> " +
          "<input type='text' ref='insideDomRefAll' v-on:input='showinsideDomRef'>" +
          " <p>ref在里面的元素上--全局注册 </p> " +
         "</div>",
    methods:{
      showinsideDomRef:function () {
        console.log(this); //这里的this其实还是div.insideFather
        console.log(this.$refs.insideDomRefAll); // <input type="text">
      }
    }
  });
  var refinsidedomall=new Vue({
    el:"#ref-inside-dom-all"
  });

二、应注意的坑

1、如果通过v-for 遍历想加不同的ref时记得加 :号,即 :ref =某变量 ;

这点和其他属性一样,如果是固定值就不需要加 :号,如果是变量记得加 :号

2、通过 :ref =某变量 添加ref(即加了:号) ,如果想获取该ref时需要加 [0],如this.$refs[refsArrayItem] [0];如果不是:ref =某变量的方式而是 ref =某字符串时则不需要加,如this.$refs[refsArrayItem]

加和不加[0]的区别--未展开

加和不加[0]的区别--展开了

3、想在element ui 对话框打开后取dom时,应该使用$nextTick,而不是直接使用this.$refs. imgLocal2:

    console.log('this.$refs.imgLocal2外面', this.$refs.imgLocal2);
    setTimeout(() => {
     console.log('this.$refs.imgLocal2 setTimeout', this.$refs.imgLocal2);
    }, 500); // 不推荐
    this.$nextTick(() => {
     console.log('this.$refs.imgLocal2 $nextTick', this.$refs.imgLocal2);
    });

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • vue单文件组件无法获取$refs的问题

    记录一下学习webpack+vue碰到的一个大坑,踩这个坑是我才疏学浅的表现,特此引以为戒.因为该坑实在是太坑了! 代码 header.html <body> <div id="popup-wrap"> <popup ref="popup"></popup> </div> </body> header.js import popup from '../../components/popup/po

  • Vue 解决通过this.$refs来获取DOM或者组件报错问题

    1.关于this.$refs的使用场景 如果ref属性加在普通元素上,那么this.$refs.name则指向该DOM元素 <p ref="p">hello</p> <!-- this.$refs.p 指向该DOM元素 --> 如果ref属性加在组件上,那么this.$refs.name指向该组件实例 <child-component ref="child"></child-component> <!

  • vue 父组件通过$refs获取子组件的值和方法详解

    前言 在vue项目中组件之间的通讯是很常见的问题,同时也是很重要的问题,我们大致可以将其分为三种情况: 父传子:在父组件中绑定值,在子组件中用props接收 子传父:在父组件中监听一个事件,在子组件中利用$emit触发这个事件并带上数据作为第二个参数,这时父组件中监听事件的回调函数就会被调用,回调函数的参数就是子组件带上来的数据,这样就可以在父组件中使用子组件的数据了, 兄弟之间的传递:我们可以使用事件总线(eventBus)来轻松的解决,其实就是发布订阅者模式 今天我们要看的是父组件如何直接调

  • vue.js中ref及$refs的使用方法解析

    关于ref和$refs的用法及讲解,vue.js中文社区( https://cn.vuejs.org/v2/api/#ref )是这么讲解的: ref 被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的 $refs 对象上. 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素:如果用在子组件上,引用就指向组件: vue.js中文社区文档上的说明已经就比较通俗易懂了,其实我们可以这么理解,ref和$refs其实就是用来获取/操作DOM元素的:类似于jquey中的$(".xxx

  • 关于Vue中$refs的探索浅析

    最近公司在做一个新项目,出需求,原型图,UI图,接下来就轮到我了,画页面.在画页面的过程中,涉及到父子路由,于是,便自然想到了<router-view></router-view>,按照以往的操作,确定父子关系,配置好路由,就OK了.但是,对照需求文档,仔细一看,后期联调肯定要涉及父子页面传递参数啊,比如下图: 我要在父页面拿到子页面form表单的数据, 如何做? 首先我想到的就是,通过this.router.push({name: "", params:{}

  • Vue中ref和$refs的介绍以及使用方法示例

    前言 在JavaScript中需要通过document.querySelector("#demo")来获取dom节点,然后再获取这个节点的值.在Vue中,我们不用获取dom节点,元素绑定ref之后,直接通过this.$refs即可调用,这样可以减少获取dom节点的消耗. ref介绍 ref被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs对象上.如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素:如果用在子组件上,引用就指向该子组件实例 通俗的讲,re

  • Vue 实例中使用$refs的注意事项

    在开发过程中,经常会通过实例的vm.$refs(this.$refs)取得通过ref注册过的组件,并进行相应操作,但存在取不到元素的情况,其根本原因是因为$refs只能取得mounted(渲染)之后的元素. 例如,在这种情况中,若flag从真值切换到假值取不到节点是正常的,因为v-if如果为假值,那么该节点不会被渲染. 但如果从假值切换到真值时,也可能取不到节点,这是因为渲染需要时间,通常可以使用$nextTick()解决. ... <el-table v-if="flag" r

  • 浅谈Vue.js中ref ($refs)用法举例总结

    本文介绍了Vue.js中ref ($refs)用法举例总结,分享给大家,具体如下: 看Vue.js文档中的ref部分,自己总结了下ref的使用方法以便后面查阅. 一.ref使用在外面的组件上 HTML 部分 <div id="ref-outside-component" v-on:click="consoleRef"> <component-father ref="outsideComponentRef"> </co

  • 详解Vue 实例中的生命周期钩子

    Vue 框架的入口就是 Vue 实例,其实就是框架中的 view model ,它包含页面中的业务处理逻辑.数据模型等,它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑. Vue 实例 在文档中经常会使用 vm 这个变量名表示 Vue 实例,在实例化 Vue 时,需要传入一个选项对象,它可以包含数据(data).模板(template).挂载元素(el).方法(methods).生命周期钩子(lifecyclehook)等选项. Vue 实例化的选项 需要注意的

  • Vue实例中生命周期created和mounted的区别详解

    前言 本文主要跟大家介绍了关于Vue实例中生命周期created和mounted区别的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 生命周期先上图 什么是生命周期 Vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.卸载等一系列过程,我们称这是Vue的生命周期.通俗说就是Vue实例从创建到销毁的过程,就是生命周期. 在Vue的整个生命周期中,它提供了一系列的事件,可以让我们在事件触发时注册js方法,可以让我们用自己注

  • vue实例中data使用return包裹的方法

    在简单的vue实例中看到的Vue实例中data属性是如下方式展示的: let app= newVue({ el:"#app", data:{ msg:'' }, methods:{ } }) 在使用组件化的项目中使用的是如下形式: export default{ data(){ return { showLogin:true, // def_act: '/A_VUE', msg: 'hello vue', user:'', homeContent: false, } }, method

  • 基于Vue实例对象的数据选项

    前面的话 一般地,当模板内容较简单时,使用data选项配合表达式即可.涉及到复杂逻辑时,则需要用到methods.computed.watch等方法.本文将详细介绍Vue实例对象的数据选项 data data是Vue实例的数据对象.Vue将会递归将data的属性转换为getter/setter,从而让data属性能响应数据变化 [注意]不应该对data属性使用箭头函数 <div id="app"> {{ message }} </div> <script&

  • vue项目中v-model父子组件通信的实现详解

    前言 我们在vue项目中,经常有这样的需求,父组件绑定v-model,子组件输入更改父组件v-model绑定的数值.很多朋友对这种操作不是很清楚,这需要对v-model有比较深入的了解,今天谈谈v-model. vue的双向数据绑定 v-model这个指令只能用在<input>, <select>,<textarea>这些表单元素上,所谓双向绑定,指的就是我们在js中的vue实例中的data与其渲染的dom元素上的内容保持一致,两者无论谁被改变,另一方也会相应的更新为相

  • 浅谈Vue.js 中的 v-on 事件指令的使用

    v-on 事件指令用于绑定事件. 1 基础用法 v-on 指令绑定事件后,就会监听相应的事件. html: <div id="app"> <h3>已点击 {{count}} 次</h3> <button @click="count++">点我</button> </div> 注意: @click 是 v-on:click 的简写形式, @ 即表示 v-on: . js: <script&g

  • VUE项目中加载已保存的笔记实例方法

    现在笔记内容每次改变都会进行保存操作,我们需要在应用重新打开的时候恢复数据.这里 将使用 localStorage.getItem() API.将下面的代码添加到 JavaScript 文件的最后: 一个基本的笔记编辑器 console.log('restored note:', localStorage.getItem('content')) 当刷新应用时,可以看到在浏览器控制台打印出了已经保存的笔记内容. 1. 生命周期钩子 将笔记内容恢复到 Vue 实例中的第一种方法就是在创建实例的时候设

  • 浅析Vue.js中v-bind v-model的使用和区别

    v-model 指令在表单控件元素上创建双向数据绑定,所谓双向绑定,指的就是我们在js中的vue实例中的data与其渲染的dom元素上的内容保持一致,两者无论谁被改变,另一方也会相应的更新为相同的数据 最基础的就是实现一个联动的效果 <body> <div class="app"> <span>Multiline message is:</span> <p>{{message}}</p> <br> &l

随机推荐