[ vue ] 手动实现el-select简单功能
1. 组件
<template>
<div class="mg-select">
<input
type="text"
readonly
@focus="focus"
placeholder="请选择"
@blur="blur"
:value="getValue"
/>
<Transition name="mg-options">
<div class="mg_options" v-if="showPopup">
<div class="option" v-for="item in options" :id="item[id]" @click="select(item)">
{{ item[label] }}
</div>
</div>
</Transition>
</div>
</template>
<script setup>
const emits = defineEmits(["update:modelValue"]);
const props = defineProps({
modelValue: [String, Number],
options: {
required: true,
type: Array,
},
id: {
required: true,
type: [String, Number],
},
value: {
required: true,
},
label: {
required: true,
},
});
const getValue = computed(() => {
if (!props.modelValue) return "";
const option = props.options.find((item) => item[props.value] === props.modelValue);
return option ? option[props.label] : "";
});
const showPopup = ref(false);
const focus = () => {
showPopup.value = true;
console.log("focus");
};
const blur = () => {
nextTick(() => {
showPopup.value = false;
});
};
const select = (item) => {
console.log("select", item);
emits("update:modelValue", item[props.value]);
showPopup.value = false;
};
</script>
<style lang="scss" scoped>
.mg-select {
width: 200px;
height: 38px;
border: 1px solid #bbb;
border-radius: 8px;
position: relative;
input {
width: 100%;
height: 100%;
border: none;
outline: none;
border-radius: inherit;
padding-left: 14px;
cursor: pointer;
}
.mg_options {
position: absolute;
top: 42px;
left: 0;
z-index: 1;
width: inherit;
border-radius: inherit;
overflow: hidden;
background-color: #fff;
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
border: 1px solid #e4e7ed;
padding: 8px 0;
.option {
height: 32px;
width: inherit;
line-height: 32px;
padding-left: 12px;
cursor: pointer;
&:hover {
background: #eee;
}
}
}
}
.mg-options-enter-active,
.mg-options-leave-active {
transition: all 0.3s ease-in-out;
}
.mg-options-enter-from,
.mg-options-leave-to {
transform-origin: 50% 0% 0;
transform: rotateX(90deg);
opacity: 0;
}
</style>
2. 引用组件
<template>
<div style="margin: 20px 0">bind value is {{ selected }}</div>
<div>
<MgSelect :options="options" id="id" label="name" value="id" v-model="selected" />
</div>
<div style="margin: 20px 0">bind value is {{ selected2 }}</div>
<MgSelect
:options="[
{ id: 1, name: '张三' },
{ id: 2, name: '李四' },
]"
id="id"
label="name"
value="id"
v-model="selected2"
/>
</template>
<script setup>
import MgSelect from "@/components/mg_select.vue";
const options = [
{ id: 1, name: "周杰伦" },
{ id: 2, name: "王力宏" },
{ id: 3, name: "陈奕迅" },
{ id: 4, name: "刘德华" },
{ id: 5, name: "林俊杰" },
];
const selected = ref("");
const selected2 = ref("");
</script>
<style lang="scss" scoped></style>
本想把生活活成一首诗, 时而优雅 , 时而豪放 , 结果活成了一首歌 , 时而不靠谱 , 时而不着调

浙公网安备 33010602011771号