二次封装element组件下拉框实现添加下拉框选项
二次封装element组件下拉框实现添加下拉框选项
组件功能
- 在开发项目时,产品提了新需求,需要在下拉框的地方增加一个添加选项然后发送请求,在数据库里把新数据加入字典中。
遇到的问题:
- 最初的思路是希望在下拉框里写一个添加选项按钮,点击添加选项按钮,按钮变成输入框,然后输入需要添加的选择项,输入框失焦发送请求,可后面发现失焦发请求,有那么些不合适,就使用了下面这个方案即:
- 点击添加选项,弹出对话框,在对话框的输入框内填写内容,点击确定,然后发送请求
效果演示:
下面是组件内容,因为涉及到接口(传递参数),所以内部传值可以自己根据字段定制
<template>
<el-select
v-model="labels"
:multiple="false"
:placeholder="`请选择${order}`"
ref="template"
:disabled="disabledSelect"
clearable
@visible-change="(v) => visibleChange(v, 'template')"
>
<el-option
v-for="(item, index) in labelslist"
:key="index"
:label="item[label]"
:value="item[val]"
>
{{ item[label] }}
<!-- <span style="float: left" class="span-style">{{ item.value }}</span> -->
<span style="float: right" class="span-style"></span>
<div class="flag" @click="showShipTemplate(item.code, true)"></div>
</el-option>
</el-select>
</template>
<script>
export default {
name: "selectAdd",
props: {
// 最开始的下拉列表数据
labelslist: {
type: Array,
default: [],
},
// 新增选项的接口
api: {
type: Function,
default: () => {},
},
// 新增选项的字段
// query: {
// type: String,
// default: "stationName",
// },
// 下拉框label绑定显示的字段名
label: {
type: String,
default: "label",
},
// 下拉框label绑定数据的字段名
val: {
type: String,
default: "value",
},
// 下拉框的名字
order: {
type: String,
default: "选项",
},
// 外部绑定的下拉框的数据
formVla: {
type: String,
default: "",
},
// 发送请求,需要携带的其他参数
paramsObj:{
type:Object,
default:()=>{}
},
// 是否禁用下拉框
disabledSelect: {
type: Boolean,
default: false,
},
// 添加选项的按钮是否在最上方
isUp:{
type:Boolean,
default:true
},
},
data() {
return {
// labelslist: [],
labels: "",
params: {},
};
},
created() {
this.labels = this.formVla;
},
methods: {
getData(api) {
this.params[this.label] = this.labels;
if(this.paramsObj) this.params = {...this.params,...this.paramsObj}
// console.log(this.params, "_____________23141234");
return new Promise(() => {
api(this.params)
.then((res) => {
if (res.code === "000000") {
this.$message.success("新增成功!");
this.$emit("getQueryStationList",true);
}
})
.catch(() => {
this.$message.error("数据加载失败!");
});
});
},
// 添加商品标签
showShipTemplate() {
this.$prompt(`请输入新的${this.order}`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
}).then(({ value }) => {
this.labels = value;
this.getData(this.api);
});
},
visibleChange(visible, refName) {
this.$nextTick(() => {
if (visible) {
const ref = this.$refs[refName];
let popper = ref.$refs.popper;
if (popper.$el) popper = popper.$el;
if (
!Array.from(popper.children).some(
(v) => v.className === "el-template-menu__list"
)
) {
const el = document.createElement("ul");
el.className = "el-template-menu__list";
el.style =
"border-bottom:2px solid rgb(219 225 241); padding:0; color:rgb(64 158 255);font-size: 13px;margin: 0px;text-align: center; ";
el.innerHTML = `<li class="el-cascader-node text-center" style="height:36px;line-height: 36px;">
<span class="el-cascader-node__label"><i class="font-blue el-icon-plus"></i>添加${this.order}</span>
</li>`;
// console.log(popper.childNode,'sssssssssssssss')
// console.log(popper.children[0], "231111111111");
// console.log(popper, "popper");
if(this.isUp){
popper.insertBefore(el, popper.children[0]);
}else{
popper.appendChild(el);
}
el.onclick = () => {
this.showShipTemplate(null, false);
};
}
}
});
},
},
}; </script>
// 模板内使用
<SelectAdd :labelslist="selectList" >
</SelectAdd>
selectList: [
{
value: "1",
label: "小红",
},
{
value: "2",
label: "小明",
},
{
value: "3",
label: "小李",
},
{
value: "4",
label: "小张",
},
{
value: "5",
label: "小刘",
},
],
其本质原理使用在下拉框最前面加上了一个按钮(按钮位置也可以控制,isUp参数默认最上方)
注意事项:
- getQueryStationList这个函数是组件在发送请求新增成功之后,通知父组件需要做一些操作的事件
- prop内接收的参数,type为String的,父组件在使用此组件时不需要加
:
,因为加:
传递的变量,不加传递的直接就是字符串(<SelectAdd :labelslist="selectList" val="value" label="label" > </SelectAdd>
)
具体其他的参数及用处都在代码块写备注了!!!
转载自:https://juejin.cn/post/7239187732492042300