1、需求
后台开发时,用户搜索功能经常用到。每次都写一遍用户搜索的代码,导致代码有很多冗余,而且修改起来要修改多处。所以需要自定义一个组件,来实现用户搜索功能。
一般vue和组件的交互有两种,一是通过事件,像父组件传递数据;另一种就是使用v-model。这里使用v-model即可。
我希望的调用方式比较简单,代码如下:
<user-search v-model="transferForm.userId"></user-search>
2、组件的代码编写
2.1、视图代码的编写
我的代码是基于element-ui的:
<template> <div> <el-form-item label="查找用户"> <el-col :span="18"> <el-input v-model="search" placeholder="编号、用户名、手机号码、邮箱、备注等字段"></el-input> </el-col> <el-col :span="4"> <el-button @click.prevent="searchUser">查找</el-button> </el-col> </el-form-item> <el-form-item label="导入至用户"> <el-select v-model="userId" allow-create default-first-option placeholder="请选择或者输入需要导入的用户编号"> <el-option v-for="item in searchResult" :key="item.id" :label="'编号:'+item.id+',用户名:'+item.username+',邮箱:'+item.email+',手机号:'+item.mobile+'备注:'+item.comment" :value="item.id"> </el-option> </el-select> </el-form-item> </div> </template>
2.2、接收父组件v-model的数据:
data() { return { search: "", searchResult: [], userId: undefined //组件内的userId变量 }; }, model: { prop: "modelValue" //这个定义props中那个值是v-model;字段名是随便定义的,不一定要modelValue }, props:{ modelValue:Number }, created(){ this.userId = this.modelValue //把v-model的值传给自身的userId },
2.3、当输入框变化的时候,执行查询操作
这个比较简单,直接在button上绑定事件即可
视图代码:
<el-button @click.prevent="searchUser">查找</el-button>
js代码:
methods: { searchUser() { if (this.search) { axios .get("/admin/user/importSearch.json", { params: { search: this.search } }) .then(response => { const data = response.data; if (data.result == "success") { this.searchResult = data.list; } else { this.$message.error(data.message); } }) .catch(err => { let msg = err.errmsg ? err.errmsg : err.message; this.$message.error(msg); }); } }
2.4、监听userId的变化,并发送给父组件
watch:{ userId(val){ this.$emit('input', val); //这里最重要,是触发父组件的input事件实现的。input是个特定的事件 } },
3、在组件里面调用该组件
3.1、引入该组件
import UserSearch from '../common/user-search.vue'; export default { components: { UserSearch }, //其他代码省略咯 }
3.2、调用组件
组件调用:
<user-search v-model="transferForm.userId"></user-search>
绑定数据:
export default{ data() { return { transferForm:{} } }, //其他代码省略了 }
4、组件完整代码:
<template> <div> <el-form-item label="查找用户"> <el-col :span="18"> <el-input v-model="search" placeholder="编号、用户名、手机号码、邮箱、备注等字段"></el-input> </el-col> <el-col :span="4"> <el-button @click.prevent="searchUser">查找</el-button> </el-col> </el-form-item> <el-form-item label="导入至用户"> <el-select v-model="userId" allow-create default-first-option placeholder="请选择或者输入需要导入的用户编号"> <el-option v-for="item in searchResult" :key="item.id" :label="'编号:'+item.id+',用户名:'+item.username+',邮箱:'+item.email+',手机号:'+item.mobile+'备注:'+item.comment" :value="item.id"> </el-option> </el-select> </el-form-item> </div> </template> <script> import { axios } from "init"; export default { name: "user-search", data() { return { search: "", searchResult: [], userId:undefined }; }, model: { prop: "modelValue" }, props:{ modelValue:Number }, watch: { userId(val) { this.$emit("input", val); } }, created(){ this.userId = this.modelValue }, methods: { searchUser() { if (this.search) { axios .get("/admin/user/importSearch.json", { params: { search: this.search } }) .then(response => { const data = response.data; if (data.result == "success") { this.searchResult = data.list; } else { this.$message.error(data.message); } }) .catch(err => { let msg = err.errmsg ? err.errmsg : err.message; this.$message.error(msg); }); } } } }; </script>