3

Question

Given I am in component context, how do I get the component object? By component object I mean the object you get when you import Component from 'Component.vue'.

Current progress

Here's one possibility I found.

const component = {
  methods: {
    getComponent: () => this,
    displayItem () {
      console.log('this.getComponent()', this.getComponent()) // undefined
      console.log('this', this) // component instance
      console.log('component', component) // what I need (component object)
    },
  },
}

export default component

The downside though is that it kills IDE support.

I also checked this manually.

Ideal solution

The approximation to syntax I'd like to see: this.$component.

What's the point?

  1. Instantiate components via :is="component".
  2. Perform instance of check.
3
  • Inside the component's methods you can do this. Commented Apr 16, 2018 at 19:54
  • @Phiter Nope. That's component instance. Commented Apr 16, 2018 at 20:02
  • maybe vm.$options._Ctor[0] but i'm not sure what [0] is here. Commented Aug 22, 2020 at 3:19

1 Answer 1

3

The closer you got is vm.$options:

Vue.component('some-comp', {
  template: '<p>{{ message }}</p>',
  props: {name: String},
  data() {
    return {
      message: 'Open the console!'
    }
  },
  computed: {
    example() {
      return this.message.toUpperCase();
    }
  },
  watch: {
    message() {
      console.log('watcher triggered');
    }
  },
  mounted() {
    console.log(this.$options);
    console.dir(this.$options.__proto__);
  }
});
new Vue({
  el: '#app'
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <some-comp :name="'Alice'"></some-comp>
</div>

But it seems what you want is constructor:

Vue.component('aaa-aaa', {
  template: '<div>AAA component</div>'
})
Vue.component('bbb-bbb', {
  template: '<div>BBB component</div>'
})

new Vue({
  el: '#app',
  mounted() {
    console.log(this.$refs.a1);
    console.log(this.$refs.a1.constructor);
    console.log(this.$refs.b1);
    console.log(this.$refs.b1.constructor);

    console.log('a1 a2', this.$refs.a1.constructor === this.$refs.a2.constructor)
    console.log('a1 b1', this.$refs.a1.constructor === this.$refs.b1.constructor)
    console.log('b1 b2', this.$refs.b1.constructor === this.$refs.b2.constructor)
    console.log('b2 a2', this.$refs.b2.constructor === this.$refs.a2.constructor)
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <aaa-aaa ref="a1"></aaa-aaa>
  <aaa-aaa ref="a2"></aaa-aaa>

  <bbb-bbb ref="b1"></bbb-bbb>
  <bbb-bbb ref="b2"></bbb-bbb>
</div>

Sign up to request clarification or add additional context in comments.

5 Comments

Added "What's the point" block to my question. Just checked your solution. Works for component istantiation via :is. Doesn't work for instance of check ($options are instantiated). I wonder if vue stores the clean object even. It seems as if it's Object.assing-ed somewhere and gets lost.
Look closer, there's no class involved. Your code does const component = {/* plain JS object here */}; export default component;. At no point a class is created, just a plain object.
Pardon my french : 3. My choice of wording was to simplify explanation. You can loosely consider component used in template (this) to be an "instance". And component object (options) you can consider "class". And I basically want to figure if 2 "instances" belong to same "class".
this.$options.__proto__ === component gives false. So also not applicable for instance of check. I'm thinking to compare name this.$options.name === 'component.name' -> true. But this requires strict convention (always unique name), which is sub-optimal, as I'm building a public library.
Try this.constructor

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.