You need to enable JavaScript to run this app. 如何在BootstrapVue中实现标签输入时展示建议列表并限制输入
优惠活动
大模型
产品
解决方案
定价
更多

如何在BootstrapVue中实现标签输入时展示建议列表并限制输入

实现方案

完整修改后代码

App.vue

<template>
  <div>
    <b-form-tags
      v-model="value"
      @input="resetInputValue()"
      tag-variant="success"
      :state="state"
    >
      <template v-slot="{ tags, inputId, placeholder, addTag, removeTag }">
        <b-input-group>
          <b-form-input
            v-model="newTag"
            list="my-list-id"
            :id="inputId"
            :placeholder="placeholder"
            :formatter="formatter"
            @keypress.enter="handleAddTag(addTag)"
            @input="handleInput"
          ></b-form-input>
        </b-input-group>
        <b-form-invalid-feedback :state="state">
          {{ errorMsg }}
        </b-form-invalid-feedback>
        <ul v-if="tags.length > 0" class="mb-0">
          <li
            v-for="tag in tags"
            :key="tag"
            :title="`Tag: ${tag}`"
            class="mt-2"
          >
            <span class="d-flex align-items-center">
              <span class="mr-2">{{ tag }}</span>
              <b-button
                size="sm"
                variant="outline-danger"
                @click="removeTag(tag)"
              >
                移除标签
              </b-button>
            </span>
          </li>
        </ul>
        <b-form-text v-else>
          未指定任何标签,请在上方添加新标签。
        </b-form-text>
      </template>
    </b-form-tags>
    <datalist id="my-list-id">
      <option v-for="(size, ind) in filteredSizes" :key="ind">{{ size }}</option>
    </datalist>
  </div>
</template>

<script>
export default {
  data() {
    return {
      newTag: "",
      value: [],
      sizes: ["Small", "Medium", "Large", "Extra Large"],
      errorMsg: ""
    };
  },
  computed: {
    filteredSizes() {
      // 实时过滤匹配输入内容的预设标签
      const keyword = this.newTag.trim().toLowerCase()
      if (!keyword) return this.sizes
      return this.sizes.filter(item => item.toLowerCase().includes(keyword))
    },
    state() {
      const trimVal = this.newTag.trim()
      // 空值不触发错误
      if (!trimVal) return null
      // 不在预设列表返回无效
      if (!this.sizes.includes(trimVal)) {
        this.errorMsg = "该标签不在可选范围内,无法添加"
        return false
      }
      // 重复值返回无效
      if (this.value.includes(trimVal)) {
        this.errorMsg = "重复的标签值无法再次添加!"
        return false
      }
      return true
    },
  },
  methods: {
    resetInputValue() {
      this.newTag = "";
    },
    formatter(value) {
      if (this.sizes.includes(value)) {
        return value.toUpperCase();
      }
      return value;
    },
    handleInput() {
      // 输入时触发校验更新
      this.state
    },
    handleAddTag(addTag) {
      const trimVal = this.newTag.trim()
      // 只有校验通过才允许添加标签
      if (this.state === true) {
        addTag(trimVal)
      }
    }
  },
};
</script>

核心调整说明

  • 新增filteredSizes计算属性,根据用户输入内容实时过滤预设标签列表,实现输入时自动展示匹配选项的下拉效果
  • 新增handleAddTag方法替代原有直接调用addTag的逻辑,只有输入内容在预设列表、且无重复的情况下才允许添加标签,从逻辑层面拦截非法输入
  • 优化state计算逻辑,同时校验输入值的合法性与重复性,对应展示不同的错误提示
  • 移除了datalist中原有的固定「手动选项」,避免出现不在预设列表中的可选值

内容的提问来源于stack exchange,提问作者user16272832

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 19:06:05