Vuejs Typescript 类组件 refs.focus 不起作用

Posted

技术标签:

【中文标题】Vuejs Typescript 类组件 refs.focus 不起作用【英文标题】:Vuejs Typescript class component refs.focus not working 【发布时间】:2020-05-27 04:25:32 【问题描述】:

我正在使用 Typescript Class 组件,但我遇到了这个问题,我无法使用this.$refs.<refname>.focus()

模板代码:

 <header class="py-2 px-1 m-0 row">
    <input
      type="text"
      class="form-control m-1"
      ref="searchBoard"
      placeholder="Find boards by name..."
    />
  </header>

此输入字段位于弹出窗口内。

打字稿代码:

import  Component, Vue  from "vue-property-decorator";

@Component
export default class BoardList extends Vue 

  // I added this to solve the compile error
  $refs!: 
    searchBoard: htmlInputElement;
  ;

  isShown = false;

  toggleDropdown() 
    this.isShown = !this.isShown;
    this.$refs.searchBoard.focus();
  
 

然后我得到这个错误:

这个问题在这个问题Vuejs typescript this.$refs..value does not exist中修复 补充:

  $refs!: 
    searchBoard: HTMLInputElement;
  ;

我的控制台出现新错误

[Vue warn]: Error in v-on handler: "TypeError: this.$refs.searchBoard is undefined"

found in

---> <BoardList> at src/components/boards/buttons/BoardList.vue
       <NavbarTop> at src/components/NavbarTop.vue
         <ComponentName> at src/App.vue
           <Root> vue.runtime.esm.js:619
    VueJS 

7

有没有办法做到这一点?

【问题讨论】:

HTMLFormElement 没有焦点方法。它应该改为 HTMLInputElement。 是的,我用 HTMLInputElement 更新了它,但我仍然在控制台中收到错误消息。 > “类型错误:this.$refs.searchBoard 未定义” 引用是非反应性的。您确定该元素不是有条件地呈现的(例如,在带有v-if 指令的元素中找到),并且在调用toggleDropdown 方法时它绝对可用?如果您将this.$refs 登录到控制台会发生什么? 当我控制台它现在显示元素及其属性。但是焦点()不起作用 它现在可以工作了,我在 setTimeout() 中添加了 .focus()。很奇怪 【参考方案1】:

关于setTimeout的使用:

根据您的代码时间,您的isShown 属性似乎控制$refs.searchBoard 是否在DOM 中呈现。 Vue 建议不要使用 setTimeout,而是使用 $nextTick 将操作推迟到下一个 DOM 周期:

toggleDropdown() 
  this.isShown = !this.isShown
  this.$nextTick(() => this.$refs.searchBoard.focus())

关于$refs

在您的班级中使用$refs type extension 的更简洁的替代方法是使用@Ref

@Component
export default class BoardList extends Vue 
  @Ref() readonly searchBoard!: HTMLInputElement

  toggleDropdown() 
    this.isShown = !this.isShown
    this.$nextTick(() => this.searchBoard.focus())
  

【讨论】:

谢谢,这看起来不错,但@Ref 给出 VSCode 错误“'Ref' is not defined.” 提前导入:import Ref from 'vue-property-decorator'【参考方案2】:

我能够让它工作,我在setTimeout() 中添加了.focus()

  toggleDropdown() 
    this.isShown = !this.isShown;

    setTimeout(() => 
      this.$refs.searchBoard.focus();
    , 50);
  

【讨论】:

我已经尝试过了,仍然返回错误“Uncaught TypeError: _this2.$refs.specie.focus is not a function at eval”【参考方案3】:

试试这个

toggleDropdown() 
    this.isShown = !this.isShown;
    this.$refs.searchBoard.$el.focus();

【讨论】:

请详细说明答案,以便 OP 了解您为什么认为您的解决方案是正确的。

以上是关于Vuejs Typescript 类组件 refs.focus 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Vue 类组件访问 VueJS 3 和 Typescript 中的 HTML 引用?

vuejs v3.0 中基于类组件的 vuejs 项目会发生啥?

VueJS 组件 ref 在所有阶段都未定义

在 VueJS 2 组件模板外使用带有 dom 元素的 ref 属性

vuejs typescript属性路由器不存在

在实现 Vue-Router 的 VueJS SPA 中实现嵌套的 $refs