Chcę utworzyć komponent z Vue.js zawierający etykietę i dane wejściowe. na przykład :
<label for="inputId">Label text</label>
<input id="inputId" type="text" />
Jak ustawić unikalny identyfikator dla każdej instancji składnika?
Dziękuję Ci.
Chcę utworzyć komponent z Vue.js zawierający etykietę i dane wejściowe. na przykład :
<label for="inputId">Label text</label>
<input id="inputId" type="text" />
Jak ustawić unikalny identyfikator dla każdej instancji składnika?
Dziękuję Ci.
Odpowiedzi:
Każdy komponent ma unikalny identyfikator, do którego można uzyskać dostęp jako 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>
Jeśli chcesz mieć większą kontrolę nad identyfikatorami, możesz na przykład wygenerować je w komponencie nadrzędnym.
ready
metoda została usunięta w Vue 2.0 i nowszych. Byłem bardzo zdezorientowany, gdy ready
metoda nie była wykonywana. stackoverflow.com/a/40209796/126751
data
musi być funkcją, która zwraca obiekt: vuejs.org/v2/guide/components.html#data-Must-Be-a-Function
this._uid
jest nieprawidłowe. Zamiast tego wygeneruj swój identyfikator samodzielnie, np. public id = uuid4();
Zobacz uuid4 .
Do punktu Nihata (powyżej): Evan Odradzasz używanie _uid: „Maszyna wirtualna _uid jest zarezerwowana do użytku wewnętrznego i ważne jest, aby zachować jej prywatność (i nie polegać na niej w kodzie użytkownika), aby zachować elastyczność w zmianie jej zachowanie dla potencjalnych przyszłych przypadków użycia. ... Sugerowałbym samodzielne wygenerowanie identyfikatorów UID [za pomocą modułu, globalnego miksu itp.] "
Korzystanie z sugerowanego miksera w tym problemie z GitHubem do generowania UID wydaje się lepszym podejściem:
let uuid = 0;
export default {
beforeCreate() {
this.uuid = uuid.toString();
uuid += 1;
},
};
Aktualizacja:
kod zgłosi błąd, jeśli ._uid
właściwość nie istnieje w instancji, dzięki czemu można ją zaktualizować, aby używała czegoś niestandardowego lub nowej unikalnej właściwości identyfikatora, jeśli jest dostarczana przez Vue.
Chociaż odpowiedź zxzaka jest świetna; _uid
nie jest opublikowaną właściwością API. Aby zaoszczędzić sobie bólu głowy na wypadek, gdyby zmienił się w przyszłości, możesz zaktualizować kod za pomocą jednej zmiany za pomocą wtyczki, jak poniżej.
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
właściwość już nie istnieje.
Opublikowałem wtyczkę Vue vue-unique-id do tego na npm .
Żadne z innych rozwiązań nie spełnia wymagania posiadania więcej niż jednego elementu formularza w komponencie. Oto moje podejście do wtyczki, która opiera się na wcześniej udzielonych odpowiedziach:
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;
};
});
Nie zależy to od _uid
właściwości wewnętrznej, która jest zarezerwowana do użytku wewnętrznego .
Użyj go w ten sposób w swoim komponencie:
<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" />
Aby stworzyć coś takiego:
<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" />
npm i -S lodash.uniqueid
Następnie w swoim kodzie ...
<script>
const uniqueId = require('lodash.uniqueid')
export default {
data () {
return {
id: ''
}
},
mounted () {
this.id = uniqueId()
}
}
</script>
W ten sposób nie ładujesz całej biblioteki lodash, ani nawet nie zapisujesz całej biblioteki do node_modules
.
W Vue2 użyj v-bind.
Powiedz, że mam obiekt do ankiety
<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"
i użyć index
w swoim v-bind'u.
Proste podejście, którego nie widziałem w odpowiedziach, to:
<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>
Jeśli używasz TypeScript, bez żadnej wtyczki, możesz po prostu dodać statyczny identyfikator do komponentu klasy i zwiększyć go w metodzie created (). Każdy komponent będzie miał unikalny identyfikator (dodaj prefiks ciągu, aby uniknąć kolizji z innymi komponentami, które używają tej samej końcówki)
<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>
Ten pakiet wydaje się być dobrym rozwiązaniem podstawowego problemu z posiadaniem nieunikalnych identyfikatorów w Twoim DOM w wielu komponentach:
Stosowanie komponentów to trend. Komponenty są fajne, są małe, oczywiste, łatwe w użyciu i modułowe. Dopóki nie dojdzie do własności id.
Niektóre atrybuty znaczników HTML wymagają użycia właściwości id, np. Label [for], input [form] i wiele atrybutów aria- *. Problem z id polega na tym, że nie jest on modułowy. Jeśli kilka właściwości id na stronie ma tę samą wartość, mogą one na siebie wpływać.
VueUniqIds pomaga pozbyć się tego problemu. Dostarcza zestaw dyrektyw związanych z identyfikatorem, których wartość jest automatycznie modyfikowana przez dodanie unikalnego ciągu, przy czym atrbitue jest łatwy do odczytania.
Jeśli twój uid nie jest używany przez inny składnik, mam pomysł.
uid: Math.random()
Proste i wystarczające.
Można to również osiągnąć za pomocą tego wzorca (Vue 2.0 v-bind), więc powiedzmy, że masz listę elementów do iteracji i chcesz nadać niektórym elementom dom niepowtarzalne identyfikatory.
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>
Mam nadzieję, że to pomoże