一个人全干!之后台管理中的搜索区域的展开搜索组件。

后台管理系统中大多数都有列表的搜索,那么用户的需求又需要必要时收缩搜索区域,需要时再展开。

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4c1b6d76b6b44a23a05a26f464034c73.png#pic_center)

而且怪的是他还需要一些部分不可收缩,不需要的地方才收缩。使用v-if来解决吧又不咋美观,我们还需要一个简单的动画效果。我们先写一个组件,直接上代码。

```javascript

<template>

    <div

        class="collapse-el">

        <div

            ref="CollapseElRef"

            class="collapse-el-container">

            <div class="collapse-el-container-container">

                <slot></slot>

            </div>

        </div>

        <div

            v-if="showBt"

            class="collapse-el-show-container">

            <div

                @click="handleClick"

                class="container">

                <div

                    :class="{

                        'bt':true,

                        'show':show,

                    }">

                    <SvgIcon

                        :style="'width:15px;height:15px;'"

                        name="sort-down"></SvgIcon>

                </div>

                {{show?'收缩':'展开'}}

            </div>

        </div>

    </div>

</template>

<script>

/**

* 折叠组件

*/

import {

    defineComponent,ref,toRef,

    onMounted,

    watch,onBeforeUnmount,

} from 'vue';

import SvgIcon from "@/components/svgIcon/index.vue";

export default defineComponent({

    name:'Collapse',

    components: {

        SvgIcon,

    },

    props:{

        show:{  //是否显示

            type:Boolean,

            default:true,

        },

        showBt:{  //是否显示展开按钮

            type:Boolean,

            default:false,

        },

        anchorPointSignName:{  //锚点标识(可用querySelector查询出来的标识)

            type:String,

            default:'.anchor-point-target',

        },

    },

    emits:['onClick'],

    setup(props,{emit}){

        const CollapseElRef = ref(null);

        const show = toRef(props,'show');

        const showBt = toRef(props,'showBt');

        const anchorPointSignName = toRef(props,'anchorPointSignName');

        onMounted(() => {

            const childEl = CollapseElRef.value.firstChild;

            const resizeObserver = new ResizeObserver((entries) => {

                computHeight();

            });

            resizeObserver.observe(childEl);

        });

        let timer = null;

        watch(show,(newValue)=>{

            computHeight();

        },{

            immediate:false,

        });

        /** 表示是显示的 */

        function isActive(){

            if(!CollapseElRef.value) return false;

            const elRect = CollapseElRef.value.getBoundingClientRect();

            if(elRect.top==0 && elRect.bottom==0 && elRect.left==0 && elRect.right==0) return false;

            return true;

        }

        /** 设置显示高度 */

        function computHeight(){

            clearTimeout(timer);

            timer = setTimeout(()=>{

                if (!isActive()) return;

                if(show.value){

                    const childHight = CollapseElRef.value.firstChild.getBoundingClientRect().height;

                    CollapseElRef.value.style.height = childHight + 'px';

                }else{

                    //如果是隐藏的话找出锚点元素

                    const anchorPointEl = CollapseElRef.value.querySelector(anchorPointSignName.value);

                    if(!anchorPointEl){

                        CollapseElRef.value.style.height = 0 + 'px';

                    }else{  //表示只隐藏到锚点元素

                        const parentRect = CollapseElRef.value.getBoundingClientRect();

                        const anchorPointElRect = anchorPointEl.getBoundingClientRect();

                        const height = anchorPointElRect.y - parentRect.y + anchorPointElRect.height;

                        CollapseElRef.value.style.height = height + 'px';

                    }

                }

            }, 26);

        }

        onBeforeUnmount(()=>{

            clearTimeout(timer);

        });

        /** 收缩组件点击事件,向外部抛出 */

        function handleClick(){

            emit('onClick');

        }

        return {

            CollapseElRef,

            show,

            showBt,

            handleClick,

        };

    },

});

</script>

<style lang='scss' scoped>

.collapse-el{

    position: relative;

    width: 100%;

    height: auto;

    >.collapse-el-container{

        position: relative;

        width: 100%;

        overflow: hidden;

        transition: all 0.2s;

        height: 0;

        >.collapse-el-container-container{

            position: absolute;

            top: 0;

            left: 0;

            width: 100%;

            height: fit-content;

        }

    }

    >.collapse-el-show-container{

        display: flex;

        justify-content: center;

        align-items: center;

        position: absolute;

        bottom: -7.5px;

        left: 0;

        width: 100%;

        pointer-events: none;

        >.container{

            width: fit-content;

            height: fit-content;

            cursor: pointer;

            display: flex;

            align-items: center;

            font-size: 12px;

            opacity: 0.5;

            pointer-events: initial;

            line-height: 1;

            >.bt{

                width: 15px;

                height: 15px;

                display: flex;

                justify-content: center;

                align-items: center;

                transition: all 0.2s;

                transform: rotate(0deg);

                &.show{

                    transform: rotate(180deg);

                }

            }

        }

    }

}

</style>

```

这样我们就有了一个可伸缩的容器组件,只需要把相应元素放在这个组件中就行了

```javascript

          <DifinCollapse

                :show="dataContainer.showSearch"

                :showBt="true"

                @onClick="dataContainer.showSearch=!dataContainer.showSearch">

                <el-col :span="24" :xs="24">

                    <el-form

                        :model="dataContainer.form"

                        ref="QueryFormRef"

                        :inline="true"

                        label-width="110px">

                        <el-row :gutter="0">

                            <el-col

                                class="anchor-point-target"

                                :span="6" :xs="6">

                                <el-form-item label="用户名称" prop="userName">

                                    <el-input

                                        v-model="dataContainer.form.userName"

                                        placeholder="请输入"

                                        clearable

                                        @clear="handleQuery"

                                        @keyup.enter="handleQuery"/>

                                </el-form-item>

                            </el-col>

                            <el-col :span="6" :xs="6">

                                <el-form-item label="昵称" prop="nickName">

                                    <el-input

                                        v-model="dataContainer.form.nickName"

                                        placeholder="请输入"

                                        clearable

                                        @clear="handleQuery"

                                        @keyup.enter="handleQuery"/>

                                </el-form-item>

                            </el-col>

                            <el-col :span="6" :xs="6">

                                <el-form-item label="数据编号" prop="id">

                                    <el-input

                                        v-model="dataContainer.form.id"

                                        placeholder="请输入"

                                        clearable

                                        @clear="handleQuery"

                                        @keyup.enter="handleQuery"/>

                                </el-form-item>

                            </el-col>

                            <el-col :span="6" :xs="6">

                                <el-form-item label="手机号码" prop="phone">

                                    <el-input

                                        v-model="dataContainer.form.phone"

                                        placeholder="请输入"

                                        clearable

                                        @clear="handleQuery"

                                        @keyup.enter="handleQuery"/>

                                </el-form-item>

                            </el-col>

                            <el-col :span="6" :xs="6">

                                <el-form-item label="可选择" prop="disabled">

                                    <el-select

                                        style="width:100%;"

                                        v-model="dataContainer.form.disabled"

                                        placeholder="请选择"

                                        clearable

                                        @clear="handleQuery"

                                        @change="handleQuery"

                                    >

                                        <el-option

                                            v-for="item in dataContainer.optionList"

                                            :key="item.id"

                                            :label="item.label"

                                            :value="item.value"

                                        ></el-option>

                                    </el-select>

                                </el-form-item>

                            </el-col>

                            <el-col :span="6" :xs="6">

                                <el-form-item label="邮箱" prop="email">

                                    <el-input

                                        v-model="dataContainer.form.email"

                                        placeholder="请输入"

                                        clearable

                                        @clear="handleQuery"

                                        @keyup.enter="handleQuery"/>

                                </el-form-item>

                            </el-col>

                            <el-col :span="12" :xs="12">

                                <el-form-item label=" ">

                                    <el-button

                                        type="primary"

                                        @click="handleQuery">

                                        <SvgIcon

                                            :style="'width:15px;height:15px;margin-right:5px;'"

                                            name="search-bt"></SvgIcon>

                                        查询

                                    </el-button>

                                    <el-button

                                        @click="resetQuery">

                                        <SvgIcon

                                            :style="'width:15px;height:15px;margin-right:5px;'"

                                            name="redo"></SvgIcon>

                                        重置

                                    </el-button>

                                </el-form-item>

                            </el-col>

                        </el-row>

                    </el-form>

                </el-col>

            </DifinCollapse>

```

是不是非常简单呢,我们可以指定一个元素使收缩的时候只能收缩到相应位置就行了,完美解决需求。[DEMO](https://admin.dumogu.top/main/show-list)。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容