让我们一起走向未来
🎓作者简介:全栈领域优质创作者
🌐个人主页:百锦再@新空间代码工作室
📞工作室:新空间代码工作室(提供各种软件服务)
💌个人邮箱:[15045666310@163.com]
📱个人微信:15045666310
💡座右铭:坚持自己的坚持,不要迷失自己!要快乐

目录
- 让我们一起走向未来
-
- 一、组件概述
- 二、项目结构
-
- [1. SearchComponent.vue (搜索组件)](#1. SearchComponent.vue (搜索组件))
- [2. ParentComponent.vue (父组件)](#2. ParentComponent.vue (父组件))
- 三、代码说明
-
- [1. **SearchComponent.vue 组件**](#1. SearchComponent.vue 组件)
- [2. **ParentComponent.vue 组件**](#2. ParentComponent.vue 组件)
- [3. **传递数据与 `emit` 机制**](#3. 传递数据与
emit机制)
- 四、总结

在 Vue.js 中,使用 defineModel 特性来创建一个高度可复用、灵活的搜索组件,能够简化复杂的搜索界面需求,同时增强代码的可维护性和可扩展性。本文将通过一个示例,展示如何基于 defineModel 和 emit 机制,开发一个包含输入框、下拉列表和搜索按钮的搜索组件。该组件能够动态接收传参并且根据传入的数据,动态渲染不同类型的组件。
一、组件概述

我们将开发的搜索组件包含以下几个部分:
- 输入框 (Input):用户可以输入关键字进行搜索。
- 下拉框 (Select):用户可以选择一个选项进行过滤。
- 搜索按钮 (Search Button):触发搜索操作。
此外,我们将使用 Vue.js 的 defineModel 特性来定义一个可接收不同类型输入的表单,动态地渲染 input 和 select 组件。
需求
输入框和下拉框的结构将根据传入的参数进行动态渲染,且每个组件都会有一个对应的 v-model 用来实现双向绑定。在用户操作输入框或下拉框时,组件通过 $emit 将搜索事件传递出去,供父组件使用。
传参数据的示例:
json
[
{
"type": "select", // 组件类型,表示是下拉框
"datalist": [{ "id": 1, "name": "Option 1" }, { "id": 2, "name": "Option 2" }], // 下拉框数据列表
"value": "", // 当前选中的值
"label": "选项", // 下拉框的标签
"index": 0 // 排序索引
},
{
"type": "input", // 组件类型,表示是输入框
"datalist": "", // 输入框没有数据列表
"value": "", // 输入框的初始值
"label": "关键字", // 输入框的标签
"index": 1 // 排序索引
}
]
二、项目结构

为了实现这一需求,我们需要的主要文件包括:
- SearchComponent.vue:搜索组件
- ParentComponent.vue:父组件,负责传递参数和处理搜索事件
1. SearchComponent.vue (搜索组件)
该组件负责渲染输入框、下拉框以及搜索按钮。根据传入的数据,动态生成相应的表单元素,并通过 $emit 将搜索事件发送给父组件。
vue
<template>
<div class="search-component">
<div v-for="(item, index) in searchData" :key="index" class="form-item">
<!-- 根据 type 渲染不同的组件 -->
<label :for="`search-item-${index}`">{{ item.label }}</label>
<!-- 下拉框 -->
<select v-if="item.type === 'select'" v-model="item.value" :id="`search-item-${index}`">
<option v-for="(option, idx) in item.datalist" :key="idx" :value="option.id">{{ option.name }}</option>
</select>
<!-- 输入框 -->
<input v-if="item.type === 'input'" v-model="item.value" :id="`search-item-${index}`" type="text" />
</div>
<!-- 搜索按钮 -->
<button @click="onSearch">搜索</button>
</div>
</template>
<script>
import { defineComponent, ref, toRefs } from "vue";
export default defineComponent({
name: "SearchComponent",
props: {
// 接收搜索组件的数据配置
searchData: {
type: Array,
required: true
}
},
emits: ["search"], // 定义搜索事件,供父组件监听
setup(props, { emit }) {
const { searchData } = toRefs(props);
// 搜索事件触发时,向父组件传递搜索结果
const onSearch = () => {
emit("search", searchData.value);
};
return {
searchData,
onSearch
};
}
});
</script>
<style scoped>
.search-component {
display: flex;
flex-direction: column;
}
.form-item {
margin-bottom: 10px;
}
button {
width: 100px;
padding: 5px;
margin-top: 10px;
}
</style>
2. ParentComponent.vue (父组件)

父组件负责接收搜索参数,并监听 search 事件,在事件触发时获取用户的选择值和输入框的值,并进行相应的处理(例如调用 API、过滤数据等)。
vue
<template>
<div>
<h1>搜索组件示例</h1>
<!-- 引入搜索组件 -->
<SearchComponent :searchData="searchConfig" @search="handleSearch" />
</div>
</template>
<script>
import { defineComponent, ref } from "vue";
import SearchComponent from "./SearchComponent.vue";
export default defineComponent({
name: "ParentComponent",
components: {
SearchComponent
},
setup() {
// 搜索组件的配置数据
const searchConfig = ref([
{
type: "select",
datalist: [
{ id: 1, name: "Option 1" },
{ id: 2, name: "Option 2" }
],
value: "", // 默认值为空
label: "选项",
index: 0
},
{
type: "input",
datalist: "",
value: "",
label: "关键字",
index: 1
}
]);
// 搜索事件处理
const handleSearch = (searchData) => {
// 在这里可以获取用户选择的值
const filters = searchData.map(item => {
return { label: item.label, value: item.value };
});
console.log("搜索条件:", filters);
// 在此可以进行实际的搜索操作,如请求 API 或过滤本地数据
};
return {
searchConfig,
handleSearch
};
}
});
</script>
<style scoped>
h1 {
margin-bottom: 20px;
}
</style>
三、代码说明

1. SearchComponent.vue 组件
该组件通过 v-for 遍历 searchData 数组,渲染每一个表单项。每一个表单项根据 type 字段决定渲染为输入框 (input) 还是下拉框 (select)。
-
数据传递 :父组件通过
searchData属性向子组件传递数据配置。每个配置项包含组件类型(type)、数据列表(datalist)、初始值(value)、标签(label)等。 -
动态渲染 :使用
v-if判断每个组件的类型,并根据type动态渲染相应的组件类型。 -
双向绑定 :使用
v-model双向绑定输入框和下拉框的值。这样用户在输入框或下拉框中输入或选择时,组件的value值会实时更新。 -
搜索按钮 :点击搜索按钮时,
onSearch方法会触发,向父组件通过emit发送search事件,并将searchData数据传递出去。父组件可以通过监听该事件来处理搜索逻辑。
2. ParentComponent.vue 组件

父组件接收 searchData 配置,并通过 @search 监听搜索事件。在事件处理方法 handleSearch 中,可以获取用户选择的条件,并执行搜索操作。
-
数据配置 :
searchConfig数组包含了两个搜索组件的配置项(一个select,一个input)。 -
搜索事件处理 :
handleSearch方法接收到子组件通过$emit发出的search事件,在其中处理搜索逻辑。此处可以执行后端请求、过滤本地数据等。
3. 传递数据与 emit 机制
通过 emit 机制,子组件能够将事件(如搜索操作)传递给父组件,从而实现组件间的通信。在本示例中,SearchComponent 组件触发 search 事件,父组件通过监听该事件来处理搜索条件。
四、总结

通过结合 defineComponent、v-for、v-model 和 emit 机制,Vue.js 能够实现一个灵活且高效的动态搜索组件。这个搜索组件能够根据传入的数据配置,动态渲染不同类型的输入组件(如输入框、下拉框等),并且能够通过事件机制将用户选择的条件传递给父组件进行处理。这种设计使得该搜索组件具有较高的复用性,并且能够轻松应对不同的业务场景。

