Tôi muốn tạo một thành phần với Vue.js có chứa nhãn và đầu vào. ví dụ :
<label for="inputId">Label text</label>
<input id="inputId" type="text" />
Làm cách nào để đặt một ID duy nhất cho từng phiên bản thành phần?
Cảm ơn bạn.
Tôi muốn tạo một thành phần với Vue.js có chứa nhãn và đầu vào. ví dụ :
<label for="inputId">Label text</label>
<input id="inputId" type="text" />
Làm cách nào để đặt một ID duy nhất cho từng phiên bản thành phần?
Cảm ơn bạn.
Câu trả lời:
Mỗi thành phần có một id duy nhất có thể được truy cập như 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>
Ví dụ, nếu bạn muốn kiểm soát nhiều hơn các id, hãy tạo chúng bên trong một thành phần mẹ.
readyphương thức này đã bị xóa trong Vue 2.0 trở lên. Tôi đã rất bối rối khi readyphương thức này không thực thi. stackoverflow.com/a/40209796/126751
dataphải là một hàm trả về một đối tượng: vuejs.org/v2/guide/components.html#data-Must-Be-a-Function
this._uidnó không hợp lệ. Thay vào đó, hãy tự tạo id của bạn, ví dụ: public id = uuid4();xem uuid4 .
Theo quan điểm của Nihat (ở trên): Evan Bạn đã khuyên không nên sử dụng _uid: "vm _uid được dành riêng cho mục đích sử dụng nội bộ và điều quan trọng là phải giữ nó ở chế độ riêng tư (và không dựa vào nó trong mã người dùng) để chúng tôi có thể linh hoạt thay đổi nó hành vi cho các trường hợp sử dụng tiềm năng trong tương lai. ... Tôi khuyên bạn nên tự tạo UID [sử dụng một mô-đun, một tổng hợp chung, v.v.] "
Sử dụng mixin được đề xuất trong vấn đề GitHub này để tạo UID có vẻ là một cách tiếp cận tốt hơn:
let uuid = 0;
export default {
beforeCreate() {
this.uuid = uuid.toString();
uuid += 1;
},
};
Cập nhật:
Mã sẽ gặp lỗi nếu thuộc ._uidtính không tồn tại trong phiên bản để bạn có thể cập nhật nó để sử dụng thuộc tính id duy nhất tùy chỉnh hoặc mới nếu được Vue cung cấp.
Mặc dù câu trả lời của zxzak là tuyệt vời; _uidkhông phải là tài sản api đã xuất bản. Để đỡ đau đầu trong trường hợp nó thay đổi trong tương lai, bạn có thể cập nhật mã của mình chỉ bằng một lần thay đổi với giải pháp plugin như bên dưới.
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");
}
});
}
});
_uidtính không tồn tại nữa.
Tôi đã xuất bản plugin vue-unique-id Vue cho cái này vào npm .
Không có giải pháp nào khác giải quyết yêu cầu có nhiều hơn một phần tử biểu mẫu trong thành phần của bạn. Đây là bước đi của tôi về một plugin được xây dựng dựa trên các câu trả lời đã cho trước đó:
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;
};
});
Điều này không phụ thuộc vào thuộc tính nội bộ _uidđược dành cho sử dụng nội bộ .
Sử dụng nó như thế này trong thành phần của bạn:
<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" />
Để tạo ra một cái gì đó như thế này:
<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
Sau đó, trong mã của bạn ...
<script>
const uniqueId = require('lodash.uniqueid')
export default {
data () {
return {
id: ''
}
},
mounted () {
this.id = uniqueId()
}
}
</script>
Bằng cách này, bạn sẽ không tải toàn bộ thư viện lodash hoặc thậm chí lưu toàn bộ thư viện vào node_modules.
Trong Vue2, sử dụng v-bind.
Giả sử tôi có một đối tượng cho một cuộc thăm dò
<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"và sử dụng indextrong bạn v-bind.
Một cách tiếp cận đơn giản mà tôi chưa thấy trong các câu trả lời là:
<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>
Nếu bạn đang sử dụng TypeScript mà không có bất kỳ plugin nào, bạn có thể chỉ cần thêm một id tĩnh vào thành phần lớp của mình và tăng nó trong phương thức create (). Mỗi thành phần sẽ có một id duy nhất (thêm tiền tố chuỗi để tránh va chạm với các thành phần khác sử dụng cùng một mẹo)
<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>
Gói này dường như là một giải pháp tốt cho vấn đề cơ bản là có các ID không phải là duy nhất trong DOM của bạn trên nhiều thành phần:
Đó là một xu hướng sử dụng các thành phần. Các thành phần rất tuyệt, chúng nhỏ, rõ ràng, dễ sử dụng và mô-đun. Bỏ nó đến thuộc tính id.
Một số thuộc tính thẻ HTML yêu cầu sử dụng thuộc tính id, như nhãn [for], input [form] và nhiều thuộc tính aria- *. Và vấn đề với id là nó không phải là mô-đun. Nếu một số thuộc tính id trên trang sẽ có cùng giá trị, chúng có thể ảnh hưởng lẫn nhau.
VueUniqIds giúp bạn thoát khỏi vấn đề này. Nó cung cấp tập hợp các chỉ thị liên quan đến id mà giá trị được tự động sửa đổi bằng cách thêm chuỗi duy nhất trong khi vẫn giữ cho phần đính kèm dễ đọc.
Nếu uid của bạn không được sử dụng bởi thành phần khác, tôi có một ý tưởng.
uid: Math.random()
Đơn giản và đủ.
Nó cũng có thể đạt được bằng cách sử dụng mẫu này (Vue 2.0 v-bind), vì vậy, giả sử bạn có một danh sách các mục để lặp lại và bạn muốn cung cấp một số id không có phần tử 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>
Hy vọng nó giúp