Vue 自定义仿word表单下拉框组件,让操作更符合用户习惯

2024-01-07 22:40:46

预览时显示界面

进入编辑框时

?

组件代码

<template>
    <div class = "paper-select ui-select flex flex-col full-width"   >
        <div ref="content" class="content font-s flex flex-center-cz padding-left-m padding-right-m flex-space-between"             
            @click="select" style="border:none;"  :class="[readonly === true ? 'readonly' : '']" >
            <div class="selected flex flex-center-cz text-center font-l" style="height:auto; text-align: center;font-family: FangSong;" >{{text}} </div>
            <div class="down margin-top-s pointer"  ></div>
        </div>
        <div v-if="show" class="position-relative" >
            <div class="list flex flex-col font-s scroll" :style="{left:leftValue,top:topValue,width:listWidth+'px'}">
                <div @click="inputClick" v-if="data.length>20">
                    <SearchInput  @search="search" :name="'searchOrg'" :focus="'focus'" class="margin-top-s margin-left-s margin-right-s"></SearchInput>
                </div>
                <template v-if="filterText.length>0">
                  <div  v-for="(item,index) in filterData" :key="index"
                    :class="{'active': item.value === val, 'no-acitve': item.value !== val}"
                    class="item show cannotselect pointer"
                    @click="selectItem(item.value)" >{{item.text}}</div>
                </template>
                <template v-else>
                  <div  v-for="(item,index) in allData" :key="index"
                    :class="{'active': item.value === val, 'no-acitve': item.value !== val}"
                    class="item show cannotselect pointer"
                    @click="selectItem(item.value)" >{{item.text}}</div>
                </template>
            </div>
        </div>
    </div>
</template>

<script>
    import SearchInput from "@/components/searchInput/SearchInput.vue";

     export default {
        name:"Select",
        components: {SearchInput},
        props:{
            data:{},
            readonly:{
              type: Boolean,
              default:false,
              required: false
            },
            value:{},
            result:{}
        },
        model: {
            prop: "value",
            event: "change"
        },
        watch:{
            value:{
                handler(newValue) {
                    this.val = newValue;
                    this.text = this.getText(newValue);
                },
                immediate: true,
                deep: true   //深度监听
            },
          data:{
            handler(newValue) {
              this.allData = newValue
            },
            immediate: true,
            deep: true   //深度监听
          },
        },
        data() {
            return {
                editMode:false,
                val:null,
                text:null,
                selectData:[],
                allData:[],
                filterData:[],
                filterText:'',
                show: false,
                leftValue: '',
                topValue:'',
                listWidth:''
            }
        },
        methods:{
            inputClick(event) {
                event.stopPropagation();
            },
            search(v){
                console.log(v,this.allData)
                if(v && v.length>0){
                    this.filterText = v
                    this.filterData = this.data.filter(e=>e.text.indexOf(this.filterText)>=0)
                }
            },
            updateText() {
                this.text = this.getText(this.val);
                console.log("val=====", this.val)
                console.log("text=====", this.text)
            },
            getText(value) {
                let result = ''
                if (this.data !== null && this.data !== "") {
                  let find = this.data.filter(b => b.value == value);
                  if (find.length > 0) {
                    result = find[0].text;
                  }
                }
                return result;
            },
            selectItem(value) {
                this.val = value;
                this.text = this.getText(value);
                this.show = false;
                this.filterText = ""
                this.$emit("change", this.val);
            },
            select(event) {
                console.log("click")
                event.stopPropagation();//阻止冒泡,防止触发下层点击事件
                document.addEventListener("click", this.closeList, false);// 添加监听点击事件

                let tValue = this.$el.getBoundingClientRect().top;
                let lValue = this.$el.getBoundingClientRect().left;
                let windowHeight = document.documentElement.clientHeight; // 实时屏幕高度

                let inputHeight = this.$refs['content'].clientHeight;
                this.listWidth = this.$refs['content'].clientWidth;

                console.log("listWidth",this.listWidth);

                let listHeight = 200;
                this.topValue = tValue + inputHeight + 'px';
                this.leftValue = lValue  + 'px';
                if (parseFloat(tValue) + listHeight > windowHeight) {
                    this.topValue = (parseFloat(windowHeight) - listHeight - inputHeight)  + "px";
                    console.log("tvalue1", this.tValue)
                }

                this.show = !this.show;
                this.filterText = ''
            },
            closeList() {
                document.removeEventListener("click", this.closeList, false);//关闭监听点击事件
                this.show = false;
                this.filterText = ''
            },
        }
     }
</script>

<style scoped>

.paper-select .content:hover .down   {
        display: inline-block;
        height: 0;
        width: 0;
        border-top: 7px solid rgba(0,0,0,0.3);
        border-bottom: 7px solid transparent;
        border-left: 7px solid transparent;
        border-right: 7px solid transparent;
  
    }


.ui-select .content{
    box-sizing: border-box;
    background-color: #fff;
    height: 30px;
    border-radius: 2px;
    border: 1px solid rgba(0, 0, 0, .2);
}


/* 选中区 */
.ui-select .content .selected {
    height: 28px;
    width: calc(100% - 30px);
}

.ui-select .content .selected .item{
    height: 22px;
}


/* 待选列表 */
.ui-select .list {
    background-color: #fff;
    position: fixed;
    border: 1px solid rgba(0, 0, 0, .2);
    left:0;
    top:0;
    right: 0;
    height: 200px;
    z-index: 99;
}


/* 待选列表行高 */
.ui-select .list .item {
    padding-left: 5px;
    line-height: 24px;
}

.ui-select .list .item:hover {
    background-color: rgba(0, 0, 0, .1);
}


.ui-select .list .active {
    background-color: #0091FF;
}

.ui-select .list .no-active {
    background-color: #fff;
}


</style>

使用组件

 <PagerSelect :data="hyData" ></PagerSelect>



hyData:
[
   {value:1,text:'已婚'},
   {value:0,text:'未婚'}
],

以上代码仅作参考,如需完整代码可以私信我。

文章来源:https://blog.csdn.net/gdgztt/article/details/135445369
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。