Vue.js : How to set a unique ID for each component

2020-02-16 07:19发布

I want to create a component with Vue.js containing a label and an input. for example :

<label for="inputId">Label text</label>
<input id="inputId" type="text" />

How can I set a unique ID for each component instance?

Thank you.

标签: vue.js
10条回答
\"骚年 ilove
2楼-- · 2020-02-16 07:38

Update

I published the vue-unique-id Vue plugin for this on npm.

Answer

None of the other solutions address the requirement of having more than one form element in your component. Here's my take on a plugin that builds on previously given answers:

Vue.use((Vue) => {
  // Assign a unique id to each component
  let uuid = 0;
  Vue.mixin({
    beforeCreate: function() {
      this.uuid = uuid.toString();
      uuid += 1;
    },
  });

  // Generate a component-scoped id
  Vue.prototype.$id = function(id) {
    return "uid-" + this.uuid + "-" + id;
  };
});

This doesn't rely on the internal _uid property which is reserved for internal use.

Use it like this in your component:

<label :for="$id('field1')">Field 1</label>
<input :id="$id('field1')" type="text" />

<label :for="$id('field2')">Field 2</label>
<input :id="$id('field2')" type="text" />

To produce something like this:

<label for="uid-42-field1">Field 1</label>
<input id="uid-42-field1" type="text" />

<label for="uid-42-field2">Field 2</label>
<input id="uid-42-field2" type="text" />
查看更多
甜甜的少女心
3楼-- · 2020-02-16 07:39
npm i -S lodash.uniqueid

Then in your code...

<script>
  const uniqueId = require('lodash.uniqueid')

  export default {
    data () {
      return {
        id: ''
      }
    },
    mounted () {
       this.id = uniqueId()
    }
  }
</script>

This way you're not loading the entire lodash library, or even saving the entire library to node_modules.

查看更多
姐就是有狂的资本
4楼-- · 2020-02-16 07:39

If your uid is not used by other compoment, I have an idea.

uid: Math.random()

Simple and enough.

查看更多
叼着烟拽天下
5楼-- · 2020-02-16 07:40

In Vue2, use v-bind.

Say I have an object for a poll

  <div class="options" v-for="option in poll.body.options">
    <div class="poll-item">
      <label v-bind:for="option._id" v-bind:style="{color: option.color}">{{option.text}}</label>
      <input type="radio" v-model="picked" v-bind:value="option._id" v-bind:id="option._id">
  </div>
  </div>
查看更多
Summer. ? 凉城
6楼-- · 2020-02-16 07:44

Update: Code will throw an error if ._uid property does not exist in the instance so that you can update it to use something custom or new unique id property if provided by Vue.

Although zxzak's answer is great; _uid is not a published api property. To save a headache in case it changes in the future, you can update your code with just one change with a plugin solution like below.

Vue.use({
    install: function(Vue, options) {
        Object.defineProperty(Vue.prototype, "uniqId", {
            get: function uniqId() {
                if ('_uid' in this) {
                   return this._uid;
                }
                throw new Error("_uid property does not exist");
            }
        });
    }
});
查看更多
Rolldiameter
7楼-- · 2020-02-16 07:47

A simple approach that I haven't seen in the replies is:

<template>
  <div>
    <label :for="id">Label text for {{id}}</label>
    <input :id="id" type="text" />
  </div>
</template>

<script>
import uniqueId from 'lodash-es/uniqueId'

export default {
  computed: {
    id () {
      # return this._uid
      return uniqueId('id')
    }
  }
}
</script>
查看更多
登录 后发表回答