如何在Vue.js中创建动态表单/筛选项?附功能命名咨询
专业名称
这个功能在前端开发里通常被称为 多选标签选择器(Multi-select Tag Picker),也常被叫做可搜索多选下拉组件,是表单交互中很常见的筛选/选择类组件。
Vue.js 实现示例(Vue 3 Composition API)
以下是适合新手的基础实现,包含核心功能:搜索过滤、选中项添加/移除、已选项排除在下拉列表外。
模板部分
<template> <div class="tag-picker-container"> <!-- 搜索输入框 --> <input v-model="searchQuery" type="text" placeholder="输入项名称搜索..." class="search-input" /> <!-- 过滤后的下拉选项列表 --> <ul v-if="filteredOptions.length > 0" class="options-list"> <li v-for="option in filteredOptions" :key="option.id" @click="selectOption(option)" class="option-item" > {{ option.name }} </li> </ul> <!-- 已选中的标签区域 --> <div class="selected-tags"> <span v-for="tag in selectedTags" :key="tag.id" class="tag-item" > {{ tag.name }} <button @click="removeTag(tag)" class="remove-btn">×</button> </span> </div> <!-- 用于提交的隐藏表单(和后端交互用) --> <form @submit.prevent="handleSubmit"> <input type="hidden" :value="selectedTags.map(t => t.id).join(',')" name="selectedIds"> <button type="submit" class="submit-btn">提交筛选</button> </form> </div> </template>
脚本部分
<script setup> import { ref, computed } from 'vue' // 模拟从后端获取的全量选项数据(实际项目中可通过axios/fetch请求) const allOptions = ref([ { id: 1, name: '产品A' }, { id: 2, name: '产品B' }, { id: 3, name: '产品C' }, { id: 4, name: '产品D' }, { id: 5, name: '产品E' } ]) // 搜索关键词 const searchQuery = ref('') // 已选中的标签数组 const selectedTags = ref([]) // 计算属性:过滤出可选的选项(排除已选中项,同时匹配搜索关键词) const filteredOptions = computed(() => { const selectedIds = selectedTags.value.map(tag => tag.id) return allOptions.value.filter(option => { return !selectedIds.includes(option.id) && option.name.toLowerCase().includes(searchQuery.value.toLowerCase()) }) }) // 选中选项的方法 const selectOption = (option) => { selectedTags.value.push(option) searchQuery.value = '' // 选中后清空搜索框 } // 移除已选标签的方法 const removeTag = (tag) => { const index = selectedTags.value.findIndex(t => t.id === tag.id) if (index !== -1) { selectedTags.value.splice(index, 1) } } // 表单提交处理(与后端交互的逻辑) const handleSubmit = () => { // 这里可将selectedTags的ID数组传给后端,比如用axios发送POST请求 console.log('提交的选中项ID:', selectedTags.value.map(t => t.id)) // 示例:axios.post('/api/filter', { selectedIds: selectedTags.value.map(t => t.id) }) } </script>
基础样式部分
<style scoped> .tag-picker-container { max-width: 400px; margin: 20px; } .search-input { width: 100%; padding: 8px 12px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px; } .options-list { list-style: none; padding: 0; margin: 8px 0; border: 1px solid #ddd; border-radius: 4px; max-height: 200px; overflow-y: auto; } .option-item { padding: 8px 12px; cursor: pointer; } .option-item:hover { background-color: #f5f5f5; } .selected-tags { margin: 12px 0; display: flex; flex-wrap: wrap; gap: 8px; } .tag-item { background-color: #e0f2fe; padding: 4px 8px; border-radius: 4px; display: flex; align-items: center; gap: 4px; font-size: 14px; } .remove-btn { background: none; border: none; cursor: pointer; color: #666; font-size: 16px; line-height: 1; } .submit-btn { padding: 8px 16px; background-color: #3b82f6; color: white; border: none; border-radius: 4px; cursor: pointer; } </style>
关键逻辑说明
- 搜索过滤:通过
computed计算属性实时筛选选项,同时排除已选中的项 - 选中/移除:选中时将选项加入
selectedTags数组,移除时从数组中删除,保证下拉列表不会重复显示已选项 - 表单交互:提交时可将已选项的ID数组传给后端,用于数据筛选或详情查询
内容的提问来源于stack exchange,提问作者VUELOVER
相关产品推荐
相关产品推荐

