Bootstrap

自己动手丰衣足食——自定义下拉框vue组件

在页面制作的过程中,经常需要使用到下拉框组件,有时候使用原生的select标签十分不便,因为存在shadow root,shadow root导致我们有时候修改样式时会非常麻烦

使用element UI下拉框时,又遇到了选择的选项文字内容过长,不能够及时变省略号的现象,需要再次用鼠标点击后才能生效(果然bug依旧是程序员不变的主题

虽然网上还有其他UI组件,但是因为当时我总体使用的是element UI,不方便改用其他UI组件了。

没有条件那就只有自己创造,自己动手丰衣足食。

之前我也写过一篇下拉框组件的博客:

这一次稍做修改,现在的下拉框组件由两个组件构成

实现的效果:

正文开始

构思

下拉框组件准备分成两个模块:

  • 第一块是用户能直接看到的内容框,有一个三角形箭头

  • 第二块是用户点击内容框后触发的下拉列表框

外层

首先,定义一个外部的模块组件wzc-select.vue

外部组件样式如下

旁边的三角符号为font-awesome图形,是一个免费的图标字体库

  • 使用下载

  • 如果使用main.js的话,添加 import 'font-awesome/css/font-awesome.min.css';

  • 使用CDN的话,用link引入:

  • 使用时直接在class中添加相应的图表名,如<i class="imgthree fa fa-caret-up" >i>

此外部组件调用时,可以对宽高还有placeholder进行设置

这里的数据传值由父组件传给子组件数值props来完成。

如果想要了解组件之间传值的方式,可以参考此文章:

使用props接收width、height、placeholder三个值,可以使用default去设置默认值,如果外部没有传值,就会使用default中的数值

props: {
  placeholder: {
    type: String,
    default: '请选择'
  },
  width: {
    type: Number,
    default: 180
  },
    height: {
      type: Number,
        default: 40
    },
}

部分属性使用:root的方式添加,这里可以自己了解

在vue中,可以使用compute去设置一个对象

computed: {
  styleVar() {
    return {
      '--select-height': this.height + 'px',
      '--select-width': this.width + 'px'
    }
  }
}

在div中通过:style绑定

<div class="wzc_select" :style="styleVar>

这样就可以在下面的style中写CSS时直接使用这些宽高

.wzc_select {
  border: 1px solid #E6E6E6;
  border-radius: 5px;
  height: var(--select-height);
  width: var(--select-width);
  line-height: var(--select-height);
}

外层的分为两部分,下面的Selectlist下拉框列表默认是隐藏的。

如果需要在点击弹出下拉框时增加一些动作效果的话,可以使用框住下拉框

在CSS中写入transition动画效果

.drop-down-enter {
  opacity: 0;
  transform:translate(0px, -80px) scaleY(0.2);
}
.drop-down-leave-to {
  opacity: 0;
  transform:translate(0px, -80px) scaleY(0.2);
}
.drop-down-enter-active {
	transition: all 0.5s ease-in;
}
.drop-down-leave-active {
	transition: all 0.5s ease;
}

在点击弹出和收起下拉框时需要做一个document的点击判断,如果点击在页面其他部分,就将下拉框收起

document.addEventListener("click", function( e ){
  if(_this.$refs.divSelect) {
    if ( !!_this.$refs.divSelect.contains(e.target) || !!_this.$refs.dropDown.contains(e.target) ) 
      return;
    else
      _this.isListShow = false;
  }   
})

这样经过一些的考虑和操作之后,外层的部分就已经写完了

让我们使用import将wzc-select.vue导入到页面中去吧,注意要在components中注册

导入:import wzcSelect from './wzc-select'

注册:components:{ wzcSelect }

调用: <wzc-select class="wzcs" :width="240" :height="40">wzc-select>

目前当前的效果已经有了,不过比较基础

内层

内层代码其实相对来说要简单的多,只需要展示外部传入的数据即可

在props当中接收CSS的宽高属性,和label内容与optionid属性

props: {
  // 宽
  width: {
    type: Number,
    default: -1,
  },
  // 高
  height: {
    type: Number,
    default: 34,
  },
  // 内容
  label: {
    type: String,
  },
  // id
  optionid: {
    type: String,
   },
},

在点击选择时,使用$parent去传递数据给外层wzc-select.vue组件

当然别忘记导入内层组件

import wzcOption from './wzc-option'

外层和内层结合

内层主要是一个对象,在外层使用时,可以使用slot去让内层存放在相应显示的位置

有关于slot插槽的介绍可以参考 ( 当然具体的学习得自己慢慢过一遍 ):

在父组件中调用时就可以添加完全了


  

使用showlist为测试数据

showlist: [
  {
    item_name: "选项00000000000000000000000000000",
    item_id: "0",
  },
  {
    item_name: "选项11111111111111111111111111111",
    item_id: "1",
  },
  {
    item_name: "选项222222222222222222222222222222",
    item_id: "2",
  },
  {
    item_name: "选项33333333333333333333333333333333",
    item_id: "3",
  },
],

好了,现在下拉框的实现效果就达到了需要的样式了

外层wzc-select.vue完整代码




内层wzc-option.vue完整代码