ฉันต้องการสร้างคอมโพเนนต์ด้วย 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
ไม่ถูกต้อง แทนที่จะสร้าง ID ของคุณด้วยตัวคุณเองเช่น public id = uuid4();
ดูuuid4
ในประเด็นของ Nihat (ด้านบน): Evan คุณได้แนะนำไม่ให้ใช้ _uid: "vm _uid สงวนไว้สำหรับการใช้งานภายในและสิ่งสำคัญคือต้องเก็บไว้เป็นส่วนตัว (และไม่ต้องพึ่งพารหัสผู้ใช้) เพื่อให้เรามีความยืดหยุ่นในการเปลี่ยนแปลง พฤติกรรมสำหรับกรณีการใช้งานที่อาจเกิดขึ้นในอนาคต ... ฉันขอแนะนำให้สร้าง UID ด้วยตนเอง [โดยใช้โมดูลมิกซ์อินส่วนกลาง ฯลฯ ] "
การใช้ mixin ที่แนะนำในปัญหา GitHub นี้เพื่อสร้าง UID ดูเหมือนจะเป็นแนวทางที่ดีกว่า:
let uuid = 0;
export default {
beforeCreate() {
this.uuid = uuid.toString();
uuid += 1;
},
};
อัปเดต:
รหัสจะแสดงข้อผิดพลาดหาก._uid
คุณสมบัติไม่มีอยู่ในอินสแตนซ์เพื่อให้คุณสามารถอัปเดตเพื่อใช้คุณสมบัติรหัสเฉพาะที่กำหนดเองหรือใหม่ได้หาก 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-unique-id Vue สำหรับสิ่งนี้ใน npmNPM
ไม่มีโซลูชันอื่นใดที่ตอบสนองความต้องการของการมีองค์ประกอบฟอร์มมากกว่าหนึ่งองค์ประกอบในส่วนประกอบของคุณ นี่คือสิ่งที่ฉันใช้ในปลั๊กอินที่สร้างจากคำตอบที่ให้ไว้ก่อนหน้านี้:
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 () แต่ละส่วนประกอบจะมี 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>
แพคเกจนี้ดูเหมือนจะเป็นทางออกที่ดีสำหรับปัญหาพื้นฐานของการมี ID ที่ไม่ซ้ำกันใน DOM ของคุณในหลายองค์ประกอบ:
เป็นเทรนด์ในการใช้ส่วนประกอบ ส่วนประกอบนั้นเจ๋งมีขนาดเล็กชัดเจนใช้งานง่ายและเป็นโมดูลาร์ จนกว่าจะถึงคุณสมบัติ id
แอตทริบิวต์แท็ก HTML บางอย่างต้องใช้คุณสมบัติ id เช่น label [for], input [form] และแอตทริบิวต์ aria- * จำนวนมาก และปัญหาเกี่ยวกับ id คือมันไม่ได้เป็นแบบแยกส่วน หากคุณสมบัติ id หลายรายการในเพจจะมีค่าเท่ากันก็สามารถส่งผลต่อกันและกันได้
VueUniqIds ช่วยคุณกำจัดปัญหานี้ มันมีชุดของคำสั่งที่เกี่ยวข้องกับ id ซึ่งค่าจะถูกแก้ไขโดยอัตโนมัติโดยการเพิ่มสตริงที่ไม่ซ้ำกันในขณะที่ทำให้การอ่านง่าย
หากผู้อื่นไม่ได้ใช้ uid ของคุณฉันมีความคิด
uid: Math.random()
ง่ายและเพียงพอ
นอกจากนี้ยังสามารถทำได้โดยใช้รูปแบบนี้ (Vue 2.0 v-bind) ดังนั้นสมมติว่าคุณมีรายการที่ต้องทำซ้ำและคุณต้องการให้รหัส uninque ขององค์ประกอบ 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>
หวังว่าจะช่วยได้