ラベルと入力を含むVue.jsでコンポーネントを作成したいと思います。例えば :
<label for="inputId">Label text</label>
<input id="inputId" type="text" />
各コンポーネントインスタンスに一意のIDを設定するにはどうすればよいですか?
ありがとうございました。
ラベルと入力を含むVue.jsでコンポーネントを作成したいと思います。例えば :
<label for="inputId">Label text</label>
<input id="inputId" type="text" />
各コンポーネントインスタンスに一意のIDを設定するにはどうすればよいですか?
ありがとうございました。
回答:
各コンポーネントには、としてアクセスできる一意のIDがあります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>
たとえば、IDをより詳細に制御したい場合は、親コンポーネント内で生成します。
ready
メソッドはVue 2.0以降で削除されました。ready
メソッドが実行されていなかったとき、私は非常に混乱しました。stackoverflow.com/a/40209796/126751
data
オブジェクトを返す関数である必要があります:vuejs.org/v2/guide/components.html#data-Must-Be-a-Function
Nihatの要点(上記):Evanあなたは_uidの使用を推奨していません。潜在的な将来のユースケースの動作...自分でUIDを生成することをお勧めします[モジュール、グローバルミックスインなどを使用して]。 "
このGitHubの問題で提案されているミックスインを使用してUIDを生成することは、より良いアプローチのようです。
let uuid = 0;
export default {
beforeCreate() {
this.uuid = uuid.toString();
uuid += 1;
},
};
更新:._uid
プロパティがインスタンスに存在しない
場合、コードはエラーをスローします。Vueから提供された場合、カスタムまたは新しい一意のIDプロパティを使用するように更新できます。
zxzakの答えは素晴らしいですが; _uid
は公開されたAPIプロパティではありません。頭痛の種を将来的に変更する場合に備えて、以下のようなプラグインソリューションを使用して、1回の変更でコードを更新できます。
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-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" />
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バインドで使用することです。
返信で見たことのない簡単な方法は次のとおりです。
<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を使用している場合は、クラスコンポーネントに静的IDを追加して、created()メソッドでそれをインクリメントできます。各コンポーネントには一意のIDがあります(同じヒントを使用する別のコンポーネントとの衝突を避けるために文字列の接頭辞を追加します)
<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が存在するという根本的な問題に対する優れたソリューションのようです。
コンポーネントを使用する傾向です。コンポーネントはクールで、小さく、明白で、使いやすく、モジュール式です。それがidプロパティになるまで。
一部のHTMLタグ属性では、label [for]、input [form]などのidプロパティと多くのaria- *属性を使用する必要があります。そして、idの問題は、それがモジュール式ではないことです。ページ上のいくつかのidプロパティが同じ値を持つ場合、それらは互いに影響を与える可能性があります。
VueUniqIdsは、この問題を取り除くのに役立ちます。これは、属性を読みやすくしつつ、一意の文字列を追加することによって値が自動的に変更されるid関連のディレクティブのセットを提供します。
あなたのuidが他のコンポーネントで使用されていない場合、私は考えがあります。
uid: Math.random()
シンプルで十分です。
これは、このパターン(Vue 2.0 v-bind)を使用しても実現できるため、反復処理するアイテムのリストがあり、いくつかのdom要素に非インク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>
それが役に立てば幸い