参考:

问题:

v-if this.$refs无法获取ref的值
出现了报错:

Error in nextTick: "TypeError: Cannot read property '$refs' of undefined"

通过v-if来控制子组件显示隐藏,然后发现子组件的this.$refs都是undefind.的问题

靠谱的解决方法:

  1. 上策 :不要使用ref的方法,而是使用自定义指令->自定义指令 1

  2. 中策 :修改业务逻辑:不要同时使用refv-if(这是dom的渲染机制决定的)

  3. 下策:修改业务逻辑,将v-if改成v-show(v-show和v-if的区别可以自己查下资料)

原因:

在这里插入图片描述

这位大佬说的对,出现报错的原因是:

refs不是动态,需要等页面渲染完成后才能拿到DOM元素

在这里插入图片描述

  • 这个错误提示很明显是绑定$refs的元素或组件不存在导致的,建议理清楚业务逻辑再编码,另外根据你贴的代码图,你似乎想要调用el-input这个组件的子组件上的focus()方法,
  • 根据element-ui的定义el-input组件是不存在子组件的,所以你直接以
    this.$refs.target.focus();调用即可,
  • 还有如果你的showInput方法是点击调用的话你大可不必使用nextTick,因为当你想要调用methods
    你的视图都已渲染完毕。

v-if 和 v-ref 同时出现时,将会有可能DOM渲染完毕后,由于v-if是false,从而没有渲染到v-ref,导致后续引用为空,

不信的话你把v-if改成true,再渲染一下试试,

  • 上一层受v-if的限制,可能没有显示,从而导致子节点无法获取,
  • 可以考虑把上一层节点的v-if改成v-show,
  • 或者分析一下为什么父节点没有显示,从业务逻辑上积极这个问题

另外,Vue3里,需要把ref写成下面的形式:

test.vue

<template>
  <div ref="myRef">获取单个DOM元素</div>
</template>

<script>
import { ref, onMounted } from 'vue'; //需要引用ref

export default {
  //没有在setup里设定 这步也可以,直接在函数里调用,
  setup() {
    const myRef = ref(null);  //在setup 时(也就是dom渲染完成后),设置ref的值,然后用return去获取一个ref,
    return {
      myRef
    };
  }
};
</script>

或者使用下面的方法:

【自定义指令官方文档】:除了核心功能默认内置的指令 (例如 v-model 和 v-show),Vue 也允许注册自定义指令

具体的代码实现就是,在script里面加一个自定义指令,并且定义指令内容为调用输入的聚焦

<template>
<el-input
  v-focus
  class="input-new-tag"
  v-if="inputVisible"
  v-model="inputValue"
  ref="saveTagInput"
  size="small"
  @keyup.enter.native="handleInputConfirm"
  @blur="handleInputConfirm"
>
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput">+ New Tag</el-button>
</template>

<script>
export default{
	directives: {
	  //注册一个局部的自定义指令 v-focus
	  focus: {
	    // 指令的定义
	    inserted: function (el) {
	      // 聚焦元素
	      el.querySelector('input').focus()
	    }
	  }
	}
	method:{
		showInput() {
	   this.inputVisible = true;
	   //不需要下面的ref函数也可以自动聚焦了,因为这里的element 的输入类型的指令中,聚焦函数focus()的函数功能 已经被替换为了上面自定义的focus()函数了:同理,上面的template部分的ref也已经可以去掉了
	   /*this.$nextTick(_ => {
	     this.$refs.saveTagInput.$refs.input.focus(); //可用了
	   });*/
	 },
	}
}
</script>

这样在v-if el-input显示以后就会自动聚焦了,而且也不会再报ref为空的错; 根本不需要ref了

其他的未经验证的解决方法:

1,可以采用 定时器(不推荐

2,用this.$nextTick来进行判断当前是否数据和dom已经加载完成了

this.$nextTick(() => {
        console.log(this.gain);
        this.$refs.XXX函数.focus();
      });

可以在请求数据的后面then里面写,
也可以写在数据获取到后外面方法上面,都是可以实现的。


  1. 自定义指令:除了核心功能默认内置的指令 (例如 v-model 和 v-show),Vue 也允许注册自定义指令 ↩︎

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐