Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to access a Vue Component's index — or some other unique identifier — from within its template?

If I'm creating, maybe dynamically, n number of components where each needs to refer to a unique index/id/reference from within its own template is there such a thing? I'm not using a for in loop to generate the components, so I don't think I have access to (read: already tried to use…) the $index.

I hacked together (poorly) a very bad illustration of what I'm trying to do, but I suspect there's a prebuilt method.

https://jsfiddle.net/itopizarro/dw070yyL/

like image 242
Ito Pizarro Avatar asked Dec 08 '25 07:12

Ito Pizarro


2 Answers

Well I made a whole example before I read the part about you don't want to use $index so here's example if it helps: https://jsfiddle.net/dw070yyL/1/

But you CAN use v-ref to give a child component a unique identifier, see http://vuejs.org/api/#v-ref

<bar v-ref:bar-one></bar>

Then in the parent component you can use this.$refs.barOne to reference that child component.

This also can work with lists as seen in the docs:

<bar v-ref:bar-list v-for="item in list"></bar>

Would make this.$refs.barList an array of child components

I'll also say that the way you're doing it isn't too bad, for instance this Wizard component uses a similar method by iterating through this.$children in the ready() function and setting each of their index accordingly:

  ready() {
    this.countItems = this.$children.length

    this.$children.forEach((item, index) => {
      item.index = index
    })
  }
like image 183
Jeff Avatar answered Dec 09 '25 21:12

Jeff


You can use a method to assign the index in the template without using a ready function.

Vue.component('task', {
  methods: {
    onStartGetIndex() {
      this.$index = this.$root.$children.length;
      return this.$index;
    }
  },
  template: '<li>{{ onStartGetIndex() }}</li>'
});

Or save the index in an attribute to be referenced more in your template.

Vue.component('task', {
  methods: {
    onStartGetIndex() {
      this.$index = this.$root.$children.length;
      return this.$index;
    }
  },
  template: '<li :index="onStartGetIndex()">{{ this.$index }}</li>'
});

The above two only work until a change is made and then the components refresh.

You can add a method that finds the index, and uses the length if it's not found.

  Vue.component('task', {
    methods: {
      getIndex() {
        if (this.$root.$children.indexOf(this) == -1) {
          this.$index = this.$root.$children.length;
        } else {
          return this.$root.$children.indexOf(this);
        }
      },
    },
    template: '<li>{{ getIndex() }}</li>'
  });
like image 41
tgraupmann Avatar answered Dec 09 '25 21:12

tgraupmann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!