Vue.js: Як встановити унікальний ідентифікатор для кожного екземпляра компонента?


115

Я хочу створити компонент з Vue.js, що містить мітку та вхід. наприклад :

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

Як я можу встановити унікальний ідентифікатор для кожного екземпляра компонента?

Дякую.


Існує кілька пакунків / мікшин, які ви можете переглянути: vue-ucid , vue-компонент-id , vue-uniq-ids .
— вул.

Не бачивши попереднього коментаря раніше, я також опублікував плагін Vue-unique-id Vue для цього в npm .
— bernie

Відповіді:


175

Кожен компонент має унікальний ідентифікатор, до якого можна отримати доступ this._uid.

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

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

Якщо ви хочете більше контролювати ідентифікатори, ви можете, наприклад, генерувати їх всередині батьківського компонента.


Зауважте, що readyметод було видалено у Vue 2.0 та вище. Я дуже розгубився, коли readyметод не був виконаний. stackoverflow.com/a/40209796/126751
— Брендан Вуд

1
... і dataповинна бути функцією, яка повертає об'єкт: vuejs.org/v2/guide/components.html#data-Must-Be-a-Function
— arminrosu

3
На жаль, це не працює в TypeScript, як this._uidі недійсне. Натомість генеруйте свій ідентифікатор самостійно, наприклад public id = uuid4();, див. Uuid4 .
— Ерік Вуллінгс

2
Мені довелося поставити ініціалізацію в метод beforeMount (), щоб переконатися, що ідентифікатор встановлений у DOM, коли я намагався отримати доступ до нього з методу mount ().
— Стефан Гербер


34

До точки Ніхата (вище): Еван Ви радив не використовувати _uid: "vm _uid зарезервований для внутрішнього використання, і важливо зберігати його приватним (а не покладатися на нього в коді користувача), щоб ми зберігали гнучкість змінювати його поведінка для потенційних випадків використання в майбутньому. Я б запропонував створити UID самостійно [використовуючи модуль, глобальний міксін тощо] "

Використання запропонованого Mixin у цій програмі GitHub для створення UID виглядає як кращий підхід:

let uuid = 0;

export default {
  beforeCreate() {
    this.uuid = uuid.toString();
    uuid += 1;
  },
};

Посилання на відповідний випуск GitHub тут буде дуже корисним
— Деймон

1
Ось випуск GitHub, де Еван радить не використовувати _id: github.com/vuejs/vue/isissue/5886#issuecomment-308625735
— січень

19

Оновлення: код видасть помилку, якщо ._uidвластивості в екземплярі не існує, щоб ви могли оновити її, щоб використовувати щось власні або нові унікальні властивості ідентифікатора, якщо вони надаються Vue.

Хоча відповідь zxzak чудова; _uidне є опублікованим майном api. Щоб зберегти головний біль у випадку, якщо він зміниться в майбутньому, ви можете оновити свій код лише однією зміною за допомогою додатка, як показано нижче.

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");
            }
        });
    }
});

Це все ще використовується uid, який у вашій власній відповіді визнає, що не рекомендується. Будь ласка, не публікуйте відповідей на користь поганої практики. Цю відповідь слід усунути.
— Гібридна веб-

2
Так, але у випадку, коли опубліковані api будуть змінені / видалені, їм доведеться змінити лише одне місце у всьому коді. В іншій відповіді це було за складовою. Я вже підкреслював це у назві.
— Ніхат

Також я просто оновив код, щоб він видав помилку, якщо _uidвластивості більше не існує.
— Ніхат

14

Оновлення

Я опублікував плагін Vue-unique-id Vue для цього в npm .

Відповідь

Жодне з інших рішень не відповідає вимозі мати більше одного елемента форми у вашому компоненті. Ось мій плагін, який ґрунтується на раніше заданих відповідях:

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;
  };
});

Це не покладається на внутрішню _uidвластивість, яка зарезервована для внутрішнього використання .

Використовуйте його так у своєму компоненті:

<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" />

Щоб створити щось подібне:

<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
npm i -S lodash.uniqueid

Потім у своєму коді ...

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

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

Таким чином ви не завантажуєте всю бібліотеку lodash або навіть зберігаєте всю бібліотеку node_modules.


2

У Vue2 використовуйте v-bind.

Скажіть, у мене є об’єкт для опитування

  <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>

Те, що вам слід йти, - v-for="(option, index) in poll.body.options"і використовувати indexв собі v-bind.
— Warre Buysse

1

Простий підхід, який я не бачив у відповідях:

<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>

1
Творець Vue.js каже, що вам слід уникати використання _uid, оскільки це для внутрішнього використання, і коли-небудь вони можуть його видалити або перейменувати або змінити його поведінку.
— Омід Садегі

1
Дякую, я вважаю, що це правильно. Я оновив код іншим рішенням, сподіваюся, все ще досить простим. У будь-якому випадку, ідея цього прикладу полягала у використанні обчисленої властивості.
— Крісті

uniqueId з lodash - це найкращий підхід на мою думку
— Giorgio Tempesta

1

Якщо ви використовуєте TypeScript без будь-якого плагіна, ви можете просто додати статичний ідентифікатор до компонента класу та збільшити його у створеному () методі. Кожен компонент матиме унікальний ідентифікатор (додайте рядковий префікс, щоб уникнути зіткнення з іншими компонентами, які використовують ту саму підказку)

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

<script lang="ts">
  ...
  @Component
  export default class MyComponent extends Vue {
    private id!: string;
    private static componentId = 0;
    ...
    created() {
      MyComponent.componentId += 1;
      this.id = `my-component-${MyComponent.componentId}`;
    }
 </script>

0

Цей пакет здається хорошим рішенням основної проблеми щодо наявності унікальних ідентифікаторів у вашому DOM для кількох компонентів:

vue-uniq-ids

Тенденція використання компонентів. Компоненти класні, вони невеликі, очевидні, прості у використанні та модульні. Поки це не стосується властивості id.

Для деяких атрибутів тегів HTML потрібно використовувати властивість id, наприклад, мітка [для], введення [форма] та багато атрибутів aria- *. І проблема з id полягає в тому, що він не модульний. Якщо декілька властивостей id на сторінці матимуть однакове значення, вони можуть впливати один на одного.

VueUniqIds допомагає вам позбутися цієї проблеми. Він надає набір директив, пов'язаних з id, значення яких автоматично змінюється додаванням унікальної рядки, зберігаючи attrbitue зручним для читання.


-4

Якщо ваш uid не використовується іншим компенсатором, у мене є ідея.

uid: Math.random()

Просто і досить.


3
Важко виправдати такий підхід, коли є реальна ймовірність зіткнення ідентифікатора ...
— Shadow

-7

Це також можна досягти за допомогою цього шаблону (Vue 2.0 v-bind), так що скажімо, у вас є список елементів для повторення, і ви хочете надати деякому елементу dom uninque id.

new Vue({

  el:body,
  data: {
     myElementIds : [1,2,3,4,5,6,8]
   }
})

Html

<div v-for="id in myElementIds">
    <label v-bind:for="id">Label text for {{id}}</label>
    <input v-bind:id="id" type="text" />
<div> 

Сподіваюся, це допомагає


8
Ви просто визначаєте ідентифікатор у масиві. Зовсім не вирішує оригінальне питання.
— arminrosu
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.