从与当前组件不同级别的其他组件访问 $refs

Posted

技术标签:

【中文标题】从与当前组件不同级别的其他组件访问 $refs【英文标题】:Access $refs from other components not in the same level as current component 【发布时间】:2018-07-26 20:26:09 【问题描述】:

我正在开发一个 Vue 应用程序。 它有一个标题,然后是主要内容。 嵌套和结构如下

TheHeader.vue -> TheLogin.vue

MainContent.vue -> ShoppingCart.vue -> OrderSummary.vue

我需要从OrderSummary.vue 访问TheLogin.vue 中的一个元素

this.$refs.loginPopover.$emit('open')

给我一​​个错误"Cannot read property '$emit' of undefined",所以很明显我无法从其他组件访问$refs

问题是我如何从其他组件中获取 refs? 提前致谢!

编辑 1 - 发现 $refs 仅适用于子组件。 如何访问不同级别的组件中的元素?

【问题讨论】:

你可以试试this.$root.$refs.header.$refs.login...,假设每个组件都有对其子组件的引用。听起来更像是像 VueX 或 event bus 这样的状态管理器的工作,但我不喜欢这些。 是的,我不想使用 Vuex,因为我只想在用户未登录时显示弹出框。简单的任务。 【参考方案1】:

您绝对不希望像那样通过层次结构。你正在打破封装。你想要一个global event bus。

这里有个秘密:有一个内置的,叫做$root。让你的 OrderSummary 做

this.$root.emit('openPopup');

并在您的 TheLogin 的 created 挂钩中设置一个监听器:

this.$root.on('openPopup', () => this.$emit('open'));

一般来说,你应该尽量避免使用 refs。

【讨论】:

但你为什么建议避免使用 refs? 因为它们适用于 Vue 对 DOM 的正常控制不足以满足要求的情况。【参考方案2】:

对于稍后来到这里并希望在父组件中访问 $refs 的任何人,在这种特殊情况下不用于发出事件,因为事件总线或存储就足够了,但假设您想访问父组件中的某些元素以获取它的属性如clientHeightclassList 等。然后你可以像这样访问它们:

this.$parent.$parent.$refs //you can traverse through multiple levels like this to access $ref property at the required level

【讨论】:

【参考方案3】:

您可以在您的组件上放置这样的函数来执行此操作。我把我的放在一个 Mixin 中:

  public findRefByName(refName) 
    let obj = this
    while (obj) 
      if (obj.$refs[refName]) 
        return obj.$refs[refName]
      
      obj = obj.$parent
    
    return undefined
  

我还添加了一些访问器来提供帮助:

  get mycomponent() 
    return this.findRefByName('mycomponent')
  

一旦存在,您只需执行以下操作即可访问您的组件:

this.mycomponent

【讨论】:

【参考方案4】:

感谢阿卜杜拉的提示! 就我而言,我正在寻找一个兄弟姐妹,所以如果有人来找那个,这里有一个例子:

var RefName='MyCoolReferenceName';
var MyRef,x;
for(x=0;x<this.$parent.$children.length;x++)

  if(typeof this.$parent.$children[x].$refs[RefName] !='undefined')
  MyRef=this.$parent.$children[x].$refs['LABEL_'+bGroupReady.ChildID];

if(typeof MyRef !='undefined')
  MyRef.error=true;

PS - 我这样做 MyRef.error=true 的原因是因为我对 Quasar 输入和惰性规则 =“ondemand” 的运气为零。原来你可以设置 .error=true 来激活错误消息和红色突出显示和 .clearValidation() 事件来清除它。万一有人也想这样做!

【讨论】:

以上是关于从与当前组件不同级别的其他组件访问 $refs的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 实例方法

Vue.js 实例方法

在 React 函数式组件中访问 Refs

16.如何优雅地获取跨层级组件实例(拒绝递归)

父组件访问子组件中的数据(父子组件通信案例:父组件访问子组件$refs[‘子组件‘],子组件传递数据给父组件(父组件中使用v-model))

React-父组件访问子组件内部