当前位置:首页 > 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 的实现方案: 文件上传组件 使用 element-ui 或 ant-design-…

vue循环数组实现

vue循环数组实现

vue循环数组的实现方法 在Vue中循环数组主要通过v-for指令实现,以下是几种常见用法: 基本数组循环 使用v-for指令遍历数组,可以通过(item, index)的语法获取当前项和索引值:…

vue实现网页切换

vue实现网页切换

Vue 实现网页切换的方法 在 Vue 中实现网页切换通常可以通过以下几种方式完成,具体取决于项目需求和路由管理方式。 使用 Vue Router Vue Router 是 Vue.js 官方提供的…

vue实现按钮刷新

vue实现按钮刷新

Vue 实现按钮刷新功能 在 Vue 中实现按钮刷新功能可以通过多种方式实现,具体取决于刷新需求是局部刷新还是全局刷新。以下是几种常见的方法: 使用 window.location.reload(…

vue实现好友列表

vue实现好友列表

实现好友列表的Vue组件 数据准备 在Vue组件的data中定义好友列表数据,通常是一个数组对象,每个对象包含好友的基本信息如ID、头像、昵称等。 data() { return { f…

vue怎么实现选中删除

vue怎么实现选中删除

实现选中删除功能的方法 在Vue中实现选中删除功能通常涉及以下几个关键步骤: 数据绑定与选中状态管理 使用v-model或v-for指令绑定列表数据,结合复选框或单选按钮实现选中状态管理。例如:…