Я хочу создать компонент с Vue.js, содержащий метку и ввод. например :
<label for="inputId">Label text</label>
<input id="inputId" type="text" />
Как я могу установить уникальный идентификатор для каждого экземпляра компонента?
Спасибо.
Я хочу создать компонент с Vue.js, содержащий метку и ввод. например :
<label for="inputId">Label text</label>
<input id="inputId" type="text" />
Как я могу установить уникальный идентификатор для каждого экземпляра компонента?
Спасибо.
Ответы:
Каждый компонент имеет уникальный идентификатор, к которому можно получить доступ как 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
dataдолжна быть функцией, возвращающей объект: vuejs.org/v2/guide/components.html#data-Must-Be-a-Function
this._uidнедопустимо. Вместо этого создайте свой идентификатор самостоятельно, например public id = uuid4();, см. Uuid4 .
На точку зрения Нихата (см. Выше): Эван Ю посоветовал не использовать _uid: "vm _uid зарезервирован для внутреннего использования, и важно сохранить его конфиденциальность (и не полагаться на него в пользовательском коде), чтобы мы могли гибко изменять его поведение для потенциальных вариантов использования в будущем ... Я бы посоветовал самостоятельно генерировать UID [с помощью модуля, глобального миксина и т. д.] "
Использование предлагаемого миксина в этой проблеме GitHub для генерации UID кажется лучшим подходом:
let uuid = 0;
export default {
beforeCreate() {
this.uuid = uuid.toString();
uuid += 1;
},
};
Обновление:
код выдает ошибку, если ._uidсвойство не существует в экземпляре, чтобы вы могли обновить его, чтобы использовать что-то настраиваемое или новое уникальное свойство id, если оно предоставлено 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свойство больше не существует.
Я опубликовал для этого плагин Vue vue-unique-id на 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" />
npm i -S lodash.uniqueid
Тогда в вашем коде ...
<script>
const uniqueId = require('lodash.uniqueid')
export default {
data () {
return {
id: ''
}
},
mounted () {
this.id = uniqueId()
}
}
</script>
Таким образом, вы не загружаете всю библиотеку lodash или даже не сохраняете всю библиотеку в node_modules.
В 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.
Простой подход, который я не видел в ответах:
<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>
Если вы используете TypeScript без какого-либо плагина, вы можете просто добавить статический идентификатор в свой компонент класса и увеличить его в методе created (). Каждый компонент будет иметь уникальный идентификатор (добавьте строковый префикс, чтобы избежать столкновения с другими компонентами, которые используют тот же наконечник)
<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>
Этот пакет кажется хорошим решением основной проблемы наличия неуникальных идентификаторов в вашей DOM для нескольких компонентов:
Использование компонентов - это тенденция. Компоненты классные, они маленькие, очевидные, простые в использовании и модульные. Пока дело не доходит до свойства id.
Некоторые атрибуты тегов HTML требуют использования свойства id, например label [for], input [form] и многих атрибутов aria- *. Проблема с идентификатором в том, что он не модульный. Если несколько свойств id на странице будут иметь одинаковое значение, они могут влиять друг на друга.
VueUniqIds поможет вам избавиться от этой проблемы. Он предоставляет набор директив, связанных с идентификатором, значение которых автоматически изменяется путем добавления уникальной строки, сохраняя при этом удобочитаемость атрибута.
Если ваш uid не используется другим компоментом, у меня есть идея.
uid: Math.random()
Просто и достаточно.
Этого также можно достичь с помощью этого шаблона (Vue 2.0 v-bind), поэтому предположим, что у вас есть список элементов, которые нужно перебирать, и вы хотите присвоить некоторому элементу dom уникальный идентификатор.
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>
Надеюсь, поможет