Vue.js:如何为每个组件实例设置唯一ID?

时间:2016-01-22 16:00:16

标签: vue.js

我想创建一个包含标签和输入的Vue.js组件。例如:

<label for="inputId">Label text</label>
<input id="inputId" type="text" />

如何为每个组件实例设置唯一ID?

谢谢。

15 个答案:

答案 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:

vue-uniq-ids

  

使用组件是一种趋势。组件很酷,它们很小,很明显,易于使用且模块化。直到id属性。

     

某些HTML标记属性需要使用id属性,例如label [for],input [form]和许多aria- *属性。 id的问题在于它不是模块化的。如果页面上的多个id属性具有相同的值,则它们可能会相互影响。

     

VueUniqIds帮助您摆脱此问题。它提供了一组与ID相关的指令,通过添加唯一的字符串可以自动修改值,同时保持属性的可读性。

答案 10 :(得分:0)

使用此命令:this.$options._scopeId-与“样式范围”部分中使用的标识符相同:

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> 

希望有所帮助