当前位置:首页 > VUE

vue实现一个标签选择

2026-01-07 06:44:49VUE

Vue 标签选择组件实现

基础实现

使用 Vue 的 v-for 和 v-model 指令可以快速实现标签选择功能:

<template>
  <div class="tag-selector">
    <div 
      v-for="tag in availableTags" 
      :key="tag"
      class="tag"
      :class="{ 'selected': selectedTags.includes(tag) }"
      @click="toggleTag(tag)"
    >
      {{ tag }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      availableTags: ['前端', '后端', '移动端', '数据库', '运维'],
      selectedTags: []
    }
  },
  methods: {
    toggleTag(tag) {
      const index = this.selectedTags.indexOf(tag)
      if (index === -1) {
        this.selectedTags.push(tag)
      } else {
        this.selectedTags.splice(index, 1)
      }
    }
  }
}
</script>

<style>
.tag-selector {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.tag {
  padding: 4px 12px;
  border: 1px solid #ddd;
  border-radius: 16px;
  cursor: pointer;
}
.tag.selected {
  background-color: #42b983;
  color: white;
  border-color: #42b983;
}
</style>

可编辑标签实现

实现允许用户添加新标签的功能:

vue实现一个标签选择

<template>
  <div>
    <input 
      v-model="newTag"
      @keyup.enter="addTag"
      placeholder="输入新标签"
    />
    <button @click="addTag">添加</button>

    <div class="tag-container">
      <span 
        v-for="tag in tags"
        :key="tag"
        class="tag"
        @click="removeTag(tag)"
      >
        {{ tag }} ×
      </span>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tags: ['Vue', 'React', 'Angular'],
      newTag: ''
    }
  },
  methods: {
    addTag() {
      if (this.newTag.trim() && !this.tags.includes(this.newTag)) {
        this.tags.push(this.newTag)
        this.newTag = ''
      }
    },
    removeTag(tag) {
      this.tags = this.tags.filter(t => t !== tag)
    }
  }
}
</script>

带搜索的标签选择器

结合输入搜索功能:

<template>
  <div>
    <input 
      v-model="searchQuery"
      placeholder="搜索标签..."
    />

    <div v-if="filteredTags.length">
      <div 
        v-for="tag in filteredTags"
        :key="tag"
        class="tag-item"
        @click="selectTag(tag)"
      >
        {{ tag }}
      </div>
    </div>
    <div v-else>
      没有匹配的标签
    </div>

    <div class="selected-tags">
      已选择: {{ selectedTags.join(', ') }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      allTags: ['JavaScript', 'TypeScript', 'HTML', 'CSS', 'Node.js'],
      selectedTags: [],
      searchQuery: ''
    }
  },
  computed: {
    filteredTags() {
      return this.allTags.filter(tag => 
        tag.toLowerCase().includes(this.searchQuery.toLowerCase()) &&
        !this.selectedTags.includes(tag)
      )
    }
  },
  methods: {
    selectTag(tag) {
      this.selectedTags.push(tag)
      this.searchQuery = ''
    }
  }
}
</script>

组件封装

将标签选择器封装为可复用组件:

vue实现一个标签选择

<!-- TagSelector.vue -->
<template>
  <div class="tag-selector">
    <div class="selected-tags">
      <span 
        v-for="tag in modelValue"
        :key="tag"
        class="tag"
        @click="removeTag(tag)"
      >
        {{ tag }} ×
      </span>
    </div>

    <input
      v-model="searchQuery"
      @keydown.enter="addNewTag"
      placeholder="添加标签..."
    />

    <div v-if="filteredTags.length" class="tag-options">
      <div
        v-for="tag in filteredTags"
        :key="tag"
        class="tag-option"
        @click="selectTag(tag)"
      >
        {{ tag }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    modelValue: {
      type: Array,
      required: true
    },
    availableTags: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      searchQuery: ''
    }
  },
  computed: {
    filteredTags() {
      return this.availableTags.filter(tag =>
        tag.toLowerCase().includes(this.searchQuery.toLowerCase()) &&
        !this.modelValue.includes(tag)
      )
    }
  },
  methods: {
    selectTag(tag) {
      this.$emit('update:modelValue', [...this.modelValue, tag])
      this.searchQuery = ''
    },
    removeTag(tag) {
      this.$emit('update:modelValue', this.modelValue.filter(t => t !== tag))
    },
    addNewTag() {
      if (this.searchQuery.trim() && !this.modelValue.includes(this.searchQuery)) {
        this.$emit('update:modelValue', [...this.modelValue, this.searchQuery])
        this.searchQuery = ''
      }
    }
  }
}
</script>

使用封装的组件:

<template>
  <TagSelector
    v-model="selectedTags"
    :available-tags="allTags"
  />
</template>

<script>
import TagSelector from './TagSelector.vue'

export default {
  components: { TagSelector },
  data() {
    return {
      allTags: ['Vue', 'React', 'Angular', 'Svelte'],
      selectedTags: []
    }
  }
}
</script>

第三方库方案

使用 vue-tags-input 等现成库:

npm install @voerro/vue-tagsinput
<template>
  <tags-input
    v-model="tags"
    :existing-tags="availableTags"
    :typeahead="true"
    placeholder="添加标签"
  />
</template>

<script>
import VoerroTagsInput from '@voerro/vue-tagsinput'

export default {
  components: {
    'tags-input': VoerroTagsInput
  },
  data() {
    return {
      tags: [],
      availableTags: [
        { key: 'vue', value: 'Vue.js' },
        { key: 'react', value: 'React' }
      ]
    }
  }
}
</script>

这些实现方案覆盖了从基础到高级的标签选择功能,可以根据项目需求选择合适的实现方式。

标签: 标签vue
分享给朋友:

相关文章

vue实现字母添加排序

vue实现字母添加排序

实现字母添加排序的方法 在Vue中实现字母添加排序功能,可以通过以下步骤完成: 创建Vue实例并定义数据 new Vue({ el: '#app', data: { letters…

vue实现同步

vue实现同步

Vue 实现同步的方法 在 Vue 中实现同步操作通常涉及数据绑定、状态管理和异步操作的处理。以下是几种常见的方法: 使用计算属性(Computed Properties) 计算属性基于响应式依赖进…

vue筛选实现

vue筛选实现

Vue 筛选实现方法 使用计算属性实现筛选 计算属性是 Vue 中实现数据筛选的常用方式。通过定义一个计算属性,可以根据输入的条件动态过滤数据。 <template> <div…

vue实现frame

vue实现frame

Vue 中实现 iframe 的方法 在 Vue 中可以通过直接使用 <iframe> 标签或动态绑定 src 属性来实现 iframe 功能。 基本用法 <template&g…

甘特图vue实现

甘特图vue实现

甘特图 Vue 实现方法 使用开源库 vue-ganttastic 安装依赖: npm install vue-ganttastic 基础实现代码: <template> <…

vue scrolltop 实现

vue scrolltop 实现

实现 Vue 中的 scrollTop 在 Vue 中实现滚动到顶部功能可以通过多种方式完成,包括使用原生 JavaScript、Vue 指令或第三方库。以下是几种常见的实现方法: 使用原生 Jav…