当前位置:首页 > 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>

可编辑标签实现

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

<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>

组件封装

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

<!-- 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 密码输入组件实现 基础密码输入框实现 使用 Vue 的 v-model 指令绑定数据,并通过 type="password" 设置输入类型为密码: <template>…

vue实现多标签选择器

vue实现多标签选择器

Vue 多标签选择器实现 基本结构 使用 Vue 的 v-model 和 v-for 指令构建标签选择器的基础交互。以下是一个简单的实现示例: <template> <div…

vue实现同步

vue实现同步

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

vue实现素材

vue实现素材

Vue 实现素材的方法 使用 Vue 组件管理素材 在 Vue 项目中,可以通过组件化的方式管理素材。创建一个专门的组件来加载和显示素材,例如图片、视频或音频文件。组件可以接收素材的路径或 URL 作…

vue滚动实现

vue滚动实现

Vue 滚动实现方法 使用原生滚动 在 Vue 中可以通过 ref 获取 DOM 元素,调用原生滚动方法实现滚动效果。适用于简单场景。 <template> <div ref…

vue实现ssr

vue实现ssr

Vue 实现 SSR(服务端渲染) Vue 的服务端渲染(SSR)允许在服务器端生成完整的 HTML 内容,再发送到客户端,提升首屏加载速度和 SEO 友好性。以下是实现 Vue SSR 的关键步骤和…