简体   繁体   中英

Access $refs from other components not in the same level as current component

I'm working on a Vue application. It has a header and then the main content. Nesting and structure as below

TheHeader.vue -> TheLogin.vue

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

I need to access an element in TheLogin.vue from OrderSummary.vue

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

gives me an error "Cannot read property '$emit' of undefined" so obviously I am not able to access $refs from other components.

The question is how do I get hold of refs from other components? Thanks in advance!

Edit 1 - Found out $refs works with only child components. How do I access elements across components in different level?

You definitely don't want to be reaching through the hierarchy like that. You are breaking encapsulation. You want a global event bus .

And here's a secret: there's one built in, called $root . Have your OrderSummary do

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

and set up a listener in your TheLogin's created hook:

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

In general, you should try to avoid using refs.

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

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

You can put a function like this on your component to do this. I put mine in a Mixin:

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

I also added some accessors to help:

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

And once that exists, you can access your component by simply doing:

this.mycomponent

Thanks for that tip Abdullah! In my case I was looking for a sibling, so in case someone comes looking for that, here's an example:

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 - The reason I'm doing MyRef.error=true is because I was having ZERO luck with Quasar inputs and lazy-rules="ondemand". Turns out you can just set .error=true to activate the error message and the red highlighting and .clearValidation() event to clear it back out. In case someone is trying to do that as well!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM