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>