事情是这样的 我们公司开发单页面应用时引用网上的组件库发现就是有时候不灵活("公司领导觉得那样样式的改成这样那样的 然后在全局改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>
复制代码
基本上就是这样的了 原理我代码写的很乱
所有评论(0)