Vue.js: Bagaimana cara mengatur ID unik untuk setiap instance komponen?

115

Saya ingin membuat komponen dengan Vue.js yang berisi label dan input. sebagai contoh :

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

Bagaimana saya bisa mengatur ID unik untuk setiap contoh komponen?

Terima kasih.

PierreB
sumber
Ada beberapa paket / mixin yang bisa Anda lihat: vue-ucid , vue-component-id , vue-uniq-ids .
str
Karena belum pernah melihat komentar sebelumnya, saya juga menerbitkan plugin vue-unique-id Vue untuk ini di npm .
bernie

Jawaban:

175

Setiap komponen memiliki id unik yang dapat diakses sebagai 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>

Jika Anda ingin lebih mengontrol id, Anda bisa misalnya, menghasilkannya di dalam komponen induk.

zxzak
sumber
Perhatikan bahwa readymetode ini telah dihapus di Vue 2.0 dan yang lebih baru. Saya sangat bingung ketika readymetode tersebut tidak dijalankan. stackoverflow.com/a/40209796/126751
Brendan Wood
1
... dan dataharus menjadi fungsi yang mengembalikan objek: vuejs.org/v2/guide/components.html#data-Must-Be-a-Function
arminrosu
3
Sayangnya, ini tidak berfungsi di TypeScript, karena this._uidtidak valid. Sebagai gantinya, buat id Anda sendiri, misalnya public id = uuid4();, lihat uuid4 .
Erik Vullings
2
Saya harus meletakkan inisialisasi dalam metode beforeMount () untuk memastikan id disetel di DOM ketika saya mencoba mengaksesnya dari metode mount ().
Stéphane Gerber
34

Untuk poin Nihat (di atas): Evan Anda telah menyarankan untuk tidak menggunakan _uid: "vm _uid dicadangkan untuk penggunaan internal dan penting untuk membuatnya tetap pribadi (dan tidak bergantung padanya dalam kode pengguna) sehingga kami menjaga fleksibilitas untuk perilaku untuk kasus penggunaan potensial di masa mendatang. ... Saya sarankan untuk membuat UID sendiri [menggunakan modul, mixin global, dll.] "

Menggunakan mixin yang disarankan dalam masalah GitHub ini untuk menghasilkan UID sepertinya pendekatan yang lebih baik:

let uuid = 0;

export default {
  beforeCreate() {
    this.uuid = uuid.toString();
    uuid += 1;
  },
};
buckthorn
sumber
tautan ke masalah GitHub terkait akan sangat berguna di sini
Damon
1
Berikut adalah masalah GitHub di mana Evan menyarankan agar tidak menggunakan _id: github.com/vuejs/vue/issues/5886#issuecomment-308625735
jannej
19

Pembaruan: Kode akan memunculkan kesalahan jika ._uidproperti tidak ada dalam contoh sehingga Anda dapat memperbaruinya untuk menggunakan sesuatu yang khusus atau properti id unik baru jika disediakan oleh Vue.

Meskipun jawaban zxzak bagus; _uidbukan properti api yang diterbitkan. Untuk menghindari sakit kepala jika terjadi perubahan di masa mendatang, Anda dapat memperbarui kode Anda hanya dengan satu perubahan dengan solusi plugin seperti di bawah ini.

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");
            }
        });
    }
});
Nihat
sumber
Ini masih menggunakan uid, yang menurut jawaban Anda sendiri tidak disarankan. Harap jangan memposting jawaban yang mendukung praktik buruk. Jawaban ini harus dihilangkan.
Pengembang web hibrid
2
Ya, tetapi jika api yang diterbitkan diubah / dihapus, mereka hanya perlu mengubah satu tempat di seluruh kode. Di jawaban lain, itu per komponen. Saya sudah menekankan itu di judul.
Nihat
Juga, saya baru saja memperbarui kode sehingga akan menimbulkan kesalahan jika _uidproperti tidak ada lagi.
Nihat
14

Memperbarui

Saya menerbitkan plugin vue-unique-id Vue untuk ini di npm .

Menjawab

Tidak ada solusi lain yang memenuhi persyaratan untuk memiliki lebih dari satu elemen formulir di komponen Anda. Inilah pendapat saya tentang plugin yang dibangun di atas jawaban yang diberikan sebelumnya:

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

Ini tidak bergantung pada _uidproperti internal yang dicadangkan untuk penggunaan internal .

Gunakan seperti ini di komponen Anda:

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

Untuk menghasilkan sesuatu seperti ini:

<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" />
Bernie
sumber
3
npm i -S lodash.uniqueid

Kemudian di kode Anda ...

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

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

Dengan cara ini Anda tidak memuat seluruh perpustakaan lodash, atau bahkan menyimpan seluruh perpustakaan ke node_modules.

meconroy.dll
sumber
2

Di Vue2, gunakan v-bind.

Katakanlah saya punya objek untuk polling

  <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>
趙曉明
sumber
Apa yang harus Anda lakukan adalah v-for="(option, index) in poll.body.options", dan gunakan indexdalam v-bind.
Warre Buysse
1

Pendekatan sederhana yang belum saya lihat di balasan adalah:

<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>
Cristi Draghici
sumber
1
Pencipta Vue.js mengatakan Anda harus menghindari penggunaan _uid karena ini untuk penggunaan internal dan suatu hari nanti mereka dapat menghapus atau mengganti nama atau mengubah perilakunya.
Omid Sadeghi
1
Terima kasih, saya pikir itu benar. Saya telah memperbarui kode dengan solusi yang berbeda, semoga masih cukup sederhana. Bagaimanapun, ide dari contoh ini adalah menggunakan properti yang dihitung.
Cristi Draghici
uniqueId dari lodash adalah pendekatan terbaik menurut saya
Giorgio Tempesta
1

Jika Anda menggunakan TypeScript, tanpa plugin apa pun, Anda cukup menambahkan id statis di komponen kelas Anda dan menaikkannya dalam metode create (). Setiap komponen akan memiliki id unik (tambahkan awalan string untuk menghindari benturan dengan komponen lain yang menggunakan tip yang sama)

<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>
JMess
sumber
0

Paket ini tampaknya menjadi solusi yang baik untuk masalah mendasar memiliki ID tidak unik di DOM Anda di beberapa komponen:

vue-uniq-ids

Ini adalah tren untuk menggunakan komponen. Komponennya keren, kecil, jelas, mudah digunakan dan modular. Sampai itu datang ke properti id.

Beberapa atribut tag HTML memerlukan penggunaan properti id, seperti label [for], input [form] dan banyak atribut aria- *. Dan masalah dengan id adalah tidak modular. Jika beberapa properti id pada halaman akan memiliki nilai yang sama, mereka dapat saling mempengaruhi.

VueUniqIds membantu Anda menyingkirkan masalah ini. Ini menyediakan sekumpulan arahan terkait id yang nilainya secara otomatis dimodifikasi dengan menambahkan string unik sambil menjaga attrbitue mudah dibaca.

berusaha keras
sumber
-4

Jika uid Anda tidak digunakan oleh perusahaan lain, saya punya ide.

uid: Math.random()

Sederhana dan cukup.

YinPeng.Wei
sumber
3
Sulit untuk membenarkan pendekatan ini ketika ada peluang nyata dari benturan id ...
Shadow
-7

Ini juga dapat dicapai dengan menggunakan pola ini (Vue 2.0 v-bind), jadi katakanlah Anda memiliki daftar item untuk mengulang dan Anda ingin memberikan beberapa elemen 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> 

Semoga membantu

pitaside
sumber
8
Anda cukup mendefinisikan ID dalam larik. Tidak menyelesaikan pertanyaan awal sama sekali.
arminrosu