框选功能(Vue)

<template>
    <div class="box" @mousedown="handleMouseDown">
        <div class="mask" v-show="is_show_mask" :style="'width:' + mask_width + 'left:' + mask_left + 'height:' + mask_height + 'top:' + mask_top"></div>
            <el-checkbox-group v-model="select_list">
                <el-checkbox v-for="(item, index) in data_list" :label="item.city_id" :key="index">
                    <p @click.stop.prevent>{{ item.city_name }}</p>
                </el-checkbox>
            </el-checkbox-group>
    </div>
</template>

<script>
export default {
    props: {},
    data() {
        return {
            data_list: [
                { city_id: 35, city_name: "香港特別行" },
                { city_id: 34, city_name: "北京市" },
                { city_id: 33, city_name: "江苏省" },
                { city_id: 32, city_name: "吉林省" },
                { city_id: 31, city_name: "内蒙古自治区" },
                { city_id: 30, city_name: "内蒙古自治区" },
                { city_id: 29, city_name: "内蒙古自治区" },
                { city_id: 28, city_name: "内蒙古自治区" },
                { city_id: 26, city_name: "内蒙古自治区" },
                { city_id: 25, city_name: "内蒙古自治区" },
            ],
            select_list: [],
            is_show_mask: false,
            box_screen_left: 0,
            box_screen_top: 0,
            start_x: 0,
            start_y: 0,
            end_x: 0,
            end_y: 0,
        };
    },
    computed: {
        mask_width() {
            return `${Math.abs(this.end_x - this.start_x)}px;`;
        },
        mask_height() {
            return `${Math.abs(this.end_y - this.start_y)}px;`;
        },
        mask_left() {
            return `${Math.min(this.start_x, this.end_x) - this.box_screen_left}px;`;
        },
        mask_top() {
            return `${Math.min(this.start_y, this.end_y) - this.box_screen_top}px;`;
        },
    },
    created() {},
    mounted() {
        const dom_box = document.querySelector(".box");
        this.box_screen_left = dom_box.getBoundingClientRect().left;
        this.box_screen_top = dom_box.getBoundingClientRect().top;
    },
    watch: {},
    methods: {
        /* 方法 */
        handleMouseDown(event) {
            if (event.target.tagName === "SPAN") return false;
            this.is_show_mask = true;
            this.start_x = event.clientX;
            this.start_y = event.clientY;
            this.end_x = event.clientX;
            this.end_y = event.clientY;
            document.body.addEventListener("mousemove", this.handleMouseMove);
            document.body.addEventListener("mouseup", this.handleMouseUp);
        },
        handleMouseMove(event) {
            this.end_x = event.clientX;
            this.end_y = event.clientY;
        },
        handleMouseUp() {
            document.body.removeEventListener("mousemove", this.handleMouseMove);
            document.body.removeEventListener("mouseup", this.handleMouseUp);
            this.is_show_mask = false;
            this.handleDomSelect();
            this.resSetXY();
        },
        handleDomSelect() {
            const dom_mask = window.document.querySelector(".mask");
            const rect_select = dom_mask.getClientRects()[0];
            const add_list = [];
            const del_list = [];
            document.querySelectorAll(".el-checkbox-group .el-checkbox").forEach((node, index) => {
                const rects = node.getClientRects()[0];
                if (this.collide(rects, rect_select) === true) {
                    if (this.select_list.includes(this.data_list[index].city_id)) {
                        del_list.push(this.data_list[index].city_id);
                    } else {
                        add_list.push(this.data_list[index].city_id);
                    }
                }
            });
            this.select_list = this.select_list.concat(add_list).filter((item) => !del_list.includes(item));
        },
        // eslint-disable-next-line class-methods-use-this
        collide(rect1, rect2) {
            const maxX = Math.max(rect1.x + rect1.width, rect2.x + rect2.width);
            const maxY = Math.max(rect1.y + rect1.height, rect2.y + rect2.height);
            const minX = Math.min(rect1.x, rect2.x);
            const minY = Math.min(rect1.y, rect2.y);
            if (maxX - minX <= rect1.width + rect2.width && maxY - minY <= rect1.height + rect2.height) {
                return true;
            } else {
                return false;
            }
        },
        resSetXY() {
            this.start_x = 0;
            this.start_y = 0;
            this.end_x = 0;
            this.end_y = 0;
        },
    },
    components: {},
};
</script>

<style scoped lang="scss">
.box {
    width: 100%;
    height: 100%;
    padding: 20px;
    position: relative;
    overflow: hidden;
    user-select: none;
    .mask {
        position: absolute;
        background: #409eff;
        opacity: 0.4;
    }
    .el-checkbox-group {
        overflow: auto;
        .el-checkbox {
            width: 137px;
            margin: 0 20px 10px 0;
            float: left;
            ::v-deep .el-checkbox__input {
                padding-top: 3px;
                vertical-align: top;
            }
            p {
                width: 110px;
                white-space: pre-wrap;
            }
        }
    }
}
</style>

框选功能(Vue)

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值