事情是這樣的 我們公司開發單頁面應用時引用網上的元件庫發現就是有時候不靈活("公司領導覺得那樣樣式的改成這樣那樣的 然後在全域性改select元件的樣式 發現特噁心的是其它元件的樣式也改了 很火大 於是 沒辦法就自己寫一個 ")
大概的樣子
功能
template
<template>
<div class="select_container_nw" :style="{width:strtransition(sl_width)+'px'}">
<div class="select_main" @click="sllistshow" :class="{select_showlist:slshow}">
<input class="searchinput" v-model="search" @change="alldata" :placeholder="placeholder" onfocus="this.select()" v-if="filterable">
<template v-if="!filterable">
<span class="select_content" v-show="showPlaceholder" :style="{width:(strtransition(sl_width)-40)+'px'}">{{placeholder}}</span>
<span class="select_content" v-show="!showPlaceholder" :style="{width:(strtransition(sl_width)-40)+'px'}">{{label}}</span>
</template>
<span class="select_arrow" :class="{cast_rotate:!slshow}"></span>
<span class="select_arrow_after " :class="{cast_rotate:!slshow}" style="margin-top: 1px;"></span>
</div>
<transition name="el-zoom-in-top">
<div class="select_list" v-show="slshow" :style="{'min-width':strtransition(sl_width)+'px'}">
<div class="select_list_body" style="position: relative; overflow: scroll;margin-right: -17px;height: 100%;max-height:150px; margin-bottom: -17px;">
<div :style="{position:'relative',top:'0px',left:strtransition(sl_left)+'px'}">
<ul class="select_list_ul" v-if="searchData.length > 0">
<li v-for="(item,index) in searchData" :key="index" @click.stop="slchang(item,index)" :class="{current:focusIndex==index}">{{item[defaultExpandedKeys.label]}}</li>
</ul>
<ul class="select_Nolist_ul" v-else>
<li>無資料</li>
</ul>
</div>
</div>
</div>
</transition>
</div>
</template>
複製程式碼
script
<script>
export default {
name: "selectlist",
props: {
sl_width: {
//預設select長度
type: [String, Number, Array],
default: "75"
},
sl_left: {
//預設select長度
type: [String, Number, Array],
default: "0"
},
opintdata: {
//預設select資料
type: Array,
default() {
return [];
}
},
value: {
//v-model值
type: [String, Number, Array],
default: ""
},
placeholder: {
//初始顯示的內容
type: String,
default: "請選擇"
},
filterable: {
//是否開啟搜尋功能
type: Boolean,
default: false
},
disabled: {//是否禁用當前元件
type: Boolean,
default: false
},
newlabel:{
type: String,
default: "請選擇"
},
defaultExpandedKeys: {//初始繫結的鍵值
type: [Array, Object],
default() {
return {
label: 'label',
value: 'value',
};
}
}
},
data() {
return {
slshow: false,
focusIndex: -1,
model: this.value,
showPlaceholder: true,
label: "",
search: "",
isshowalldata: true,
};
},
created() {
this.opintchang();
},
mounted() {
document.addEventListener('click', (e) => {
if (!this.$el.contains(e.target)) this.slshow = false;
})
},
watch: {
value(val) {
this.model = val;
this.opintchang();
},
opintdata(val) {
this.label = this.placeholder;
this.opintchang();
},
search(val) {
this.isshowalldata = false;
},
newlabel(val){
this.label=val;
}
},
computed: {
searchData: function () {
var search = this.search;
if (this.isshowalldata && this.filterable) {
return this.opintdata
}
else if (search && this.filterable) {
return this.opintdata.filter(function (product) {
return Object.keys(product).some(function (key) {
return (
String(product[key])
.toLowerCase()
.indexOf(search) > -1
);
});
});
}
return this.opintdata;
}
},
methods: {
alldata() {
},
strtransition(str) {
//處理處進來的長度
if (parseInt(str) != NaN) {
return parseInt(str);
} else {
return 115;
}
},
sllistshow(e) {
//控制list顯示不顯示
this.isshowalldata = true;
this.slshow = !this.slshow;
},
slchang(item, index, isnotchange = true) {
//list點選事件
this.model = item[this.defaultExpandedKeys.label];
this.label = item[this.defaultExpandedKeys.label];
this.slshow = false;
this.focusIndex = index;
this.showPlaceholder = false;
this.$emit("input", item[this.defaultExpandedKeys.value]); //觸發 input 事件,並傳入新值
if (isnotchange) {
this.search = item[this.defaultExpandedKeys.label];
}
this.$emit("change", item, index);
},
handleClose() {
//關閉list列表
this.slshow = false;
},
opintchang() {
if (typeof this.opintdata == "object") {
let pi = this.opintdata.filter(item => {
if (this.value == item[this.defaultExpandedKeys.value]) {
return item;
}
})
let index = 0;
let item = {};
if (pi.length > 0) {
index = this.opintdata.findIndex(item => {
if (this.value == item[this.defaultExpandedKeys.value]) {
return item;
}
})
item = pi[0];
} else {
item = this.opintdata.length > 0 ? this.opintdata[0] : {};
}
if (this.opintdata.length > 0) {
this.slchang(item, index, false);
this.showPlaceholder = false;
}
}
}
}
}
</script>
複製程式碼
scss
<style lang="scss" type="text/css" scoped>
$slbordercolor: #dfe4ed;
$fontcolor: #5a5e66;
.disabled {
pointer-events: none;
cursor: default;
filter: alpha(opacity=50); /*IE濾鏡,透明度50%*/
-moz-opacity: 0.5; /*Firefox私有,透明度50%*/
opacity: 0.5; /*其他,透明度50%*/
}
.select_container_nw {
/* margin-right: 10px; */
font-size: 14px;
position: relative;
font-size: 13px;
font-family: "Helvetica Neue", arial, sans-serif;
font-weight: 300;
letter-spacing: 1px;
display: inline-block;
background-color: white;
}
.select_main {
position: relative;
border-radius: 15px;
border: 1px solid #adadad;
line-height: 20px;
cursor: pointer;
}
.select_main:hover {
border-color: #409eff;
}
.select_circle {
position: absolute;
width: 16px;
border-radius: 50%;
height: 16px;
right: 6px;
top: 50%;
transform: translate3d(0, -50%, 0);
background-color: #ecf6fe;
}
.select_showlist {
border-color: #409eff;
}
.select_content {
color: #49a8f6;
display: block;
padding: 0px 10px 0px 7px;
overflow: hidden;
cursor: pointer;
user-select: none;
-webkit-user-select: none;
white-space: nowrap;
}
.select_content::after {
content: " ";
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 40px;
border-radius: 0 2px 2px 0;
}
.select_input {
padding-left: 10px;
padding-right: 32px;
font-size: 13px;
overflow: hidden;
outline: none;
height: 25px;
border: none;
border-bottom: 1px solid $slbordercolor;
z-index: 1;
}
.search_svg {
position: absolute;
top: 2px;
right: 3px;
z-index: 2;
}
.select_arrow,
.select_arrow_after {
content: " ";
position: absolute;
right: 9px;
top: 42%;
border: 4px solid transparent;
border-top: 4px solid #2988fc;
z-index: 1;
-webkit-transform-origin: 50% 20%;
-moz-transform-origin: 50% 20%;
-ms-transform-origin: 50% 20%;
transform-origin: 50% 20%;
transition: all 150ms ease-in-out;
cursor: pointer;
}
.select_arrow_after {
cursor: pointer;
margin-top: -1px;
}
.select_list {
position: absolute;
left: 0px;
top: 100%;
border: 1px solid $slbordercolor;
margin: 2px 0 0 0;
overflow: hidden;
transform-origin: center top 0px;
border-radius: 2px;
background-color: #fff;
outline: none;
z-index: 2020;
}
.select_list > .select_list_body ul {
list-style: none;
padding: 10px 0;
margin: 0;
box-sizing: border-box;
position: relative;
display: block;
}
.select_list > .select_list_body ul li {
font-size: 14px;
padding: 0 20px;
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: black;
height: 20px;
line-height: 20px;
box-sizing: border-box;
}
.select_list_ul li {
cursor: pointer;
}
.select_list_ul li:hover {
background-color: #f5f7fa;
color: $fontcolor;
}
.current {
background-color: #f5f7fa;
color: #409eff !important;
font-weight: 700;
}
.cast_rotate {
transform-origin: 50% 20%;
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}
.select_list_body {
max-height: 200px;
overflow: hidden;
}
.list_current {
display: none;
}
.searchinput {
border: none;
width: 74%;
height: 93%;
outline: none;
text-align: center;
margin: 0 0 0 7px;
&:focus {
border: none;
}
}
.no_result {
display: none;
text-align: center;
color: $slbordercolor;
}
.list_open {
display: block;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
</style>
複製程式碼
基本上就是這樣的了 原理我程式碼寫的很亂