我想创建一个包含标签和输入的Vue.js组件。例如:
<label for="inputId">Label text</label>
<input id="inputId" type="text" />
如何为每个组件实例设置唯一ID?
谢谢。
答案 0 :(得分:123)
每个组件都有一个唯一的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,例如,可以在父组件中生成它们。
答案 1 :(得分:22)
至于Nihat的观点(上图):Evan You建议不要使用_uid:“vm _uid保留供内部使用,保持私有(并且不依赖于用户代码)非常重要,这样我们就能保持灵活性改变其未来潜在用例的行为....我建议你自己生成UID [使用模块,全局混合等]。“
使用this GitHub issue中建议的mixin生成UID似乎是一种更好的方法:
let uuid = 0;
export default {
beforeCreate() {
this.uuid = uuid.toString();
uuid += 1;
},
};
答案 2 :(得分:19)
虽然zxzak的答案很棒; _uid
不是已发布的api属性。为了避免将来发生变化而感到头疼,您只需使用下面的插件解决方案进行一次更改即可更新代码。
Vue.use({
install: function(Vue, options) {
Object.defineProperty(Vue.prototype, "uniqId", {
get: function uniqId() {
return this._uid;
}
});
}
});
答案 3 :(得分:5)
npm i -S lodash.uniqueid
然后在您的代码中...
<script>
const uniqueId = require('lodash.uniqueid')
export default {
data () {
return {
id: ''
}
},
mounted () {
this.id = uniqueId()
}
}
</script>
这样,您将不会加载整个lodash库,甚至不会将整个库保存到node_modules
。
答案 4 :(得分:2)
在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>
答案 5 :(得分:2)
我在回复中没有看到的一种简单方法是:
<template>
<div>
<label :for="id">Label text for {{id}}</label>
<input :id="id" type="text" />
</div>
</template>
<script>
export default {
computed: {
id () {
return this._uid
}
}
}
</script>
答案 6 :(得分:2)
我发布了vue-unique-id Vue plugin for this on 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
属性reserved for internal use。
在您的组件中像这样使用它:
<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" />
答案 7 :(得分:2)
如果您使用的是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>
答案 8 :(得分:1)
这似乎对我在 nuxtjs 中有效
https://www.npmjs.com/package/uuid
生成的输出示例: 元素:47bfe557-d75f-455c-9a37-85b7935b297b
package.json
"dependencies": {
"uuid": "^8.3.2"
},
在子组件上,可能不是最好的方法,但似乎有效
...
<ComponentName v-if="element" />
...
import { v4 as uuidv4 } from 'uuid';
...
data() {
return {
element: null,
}
}
...
mounted() {
this.element = uuidv4();
}
答案 9 :(得分:0)
对于潜在的以下问题,该软件包似乎是一个很好的解决方案:在DOM中跨多个组件具有非唯一ID:
使用组件是一种趋势。组件很酷,它们很小,很明显,易于使用且模块化。直到id属性。
某些HTML标记属性需要使用id属性,例如label [for],input [form]和许多aria- *属性。 id的问题在于它不是模块化的。如果页面上的多个id属性具有相同的值,则它们可能会相互影响。
VueUniqIds帮助您摆脱此问题。它提供了一组与ID相关的指令,通过添加唯一的字符串可以自动修改值,同时保持属性的可读性。
答案 10 :(得分:0)
使用此命令:this.$options._scopeId
-与“样式范围”部分中使用的标识符相同:
答案 11 :(得分:0)
这似乎对我有用 https://www.npmjs.com/package/uuid
生成的输出示例: 元素:47bfe557-d75f-455c-9a37-85b7935b297b
package.json
"dependencies": {
"uuid": "^8.3.2"
},
component.vue
v-if="element"
...
import { v4 as uuidv4 } from 'uuid';
...
data() {
return {
element: null,
}
}
...
mounted() {
this.element = uuidv4();
}
答案 12 :(得分:0)
我发现的最简单的方法是通过全局 mixin 手动创建 UUID (uuid package
)。这样您就不会依赖于任何可能在未来发生变化或被弃用的内容,例如 this._uid
。
您首先必须安装 uuid
软件包:
npm i uuid
然后,在您的 main.js
文件中创建一个全局 mixin:
// rest of imports
import { v4 as uuidv4 } from 'uuid';
const app = Vue.createApp(App);
app.mixin({
data() {
return {
componentId: uuidv4()
}
},
});
app.use(store).use(router).mount('#app');
这里是如何在组件中使用它:
<template>
<div>
<h1>{{ componentId }}</h1>
<button @click="printId()">click me for componentId.</button>
</div>
</template>
<script>
export default {
methods: {
printId: function() {
console.log(this.componentId);
}
}
}
</script>
答案 13 :(得分:-2)
如果您的uid不被其他工具使用,我有个主意。
uid: Math.random()
简单而足够。
答案 14 :(得分:-6)
也可以使用这种模式(Vue 2.0 v-bind)来实现,所以假设您有一个要迭代的项目列表,并且您想要给出一些dom元素uninque 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>
希望有所帮助