阅读 1469

vue项目小效果-拖拽更改左右宽度

vue项目小效果-拖拽更改左右宽度

vue-element项目中需要有一个拖动改变宽度的效果如图:

1.封装组件(思路及问题、解决方案)

我把它封装成了组件,需要的童鞋可以拿过去直接使用,这个也是我参考其他人的,就是时间久了忘了那个博主是谁了=_=!

  • 首先要从父组件传过来的包含外层大盒子,里面的左右两边的类名对象
  • 每个人定义的类名不一样所以需要从父组件那里定义一个对象传过来,以便于得到对应的宽度进行改变大小
  • 先定义一个变量,存储当前可视区域的宽度,为了方便监听
  • 问题:因为当前窗口改变时右侧的宽度并没有随着窗口宽度变化,导致右侧留白,宽度没有自适应(当你进行拖拽时会重新获取,所以是可以的)
  • 所以在这里我进行了监听,当窗口变化时重新计算右侧的宽度进行自适应
  • 最后不要忘了组件销毁前把窗口事件监听这个方法给注销,因为这个方法是全局的,如果不注销会影响到其他页面。
    export default {    
        name: "dragAdjustWidth",   
        props:["styleLoc"], // 从父组件传过来的包含外层大盒子,里面的左右两边的类名对象    
        data() {        
            return {            
                screenWidth: document.body.clientWidth, // 获取当前可视区域的宽度        
            };    
        },    
        created() {},   
        mounted() {        
            this.dragControllerDiv();
            let _this = this;//赋值vue的this
            window.addEventListener('resize',() => {
                this.screenWidth = document.body.clientWidth
            })
        },
        watch: { 
           screenWidth(newVal, oldVal) {
                let styleLoc = this.styleLoc;
                var resize = document.getElementsByClassName('drag');
                var mid = document.getElementsByClassName(styleLoc.right);
                for (let i = 0; i < resize.length; i++) {
                    mid[i].style.width = (newVal - resize[i].offsetLeft) + 'px';
                }
            },
        },
        components: {    },
        methods: {
            dragControllerDiv () {},
            beforeDestroy () {
                window.onresize = null;
            }
        }
    };
复制代码

2.拖拽事件

终于到重点了---主要是这个方法,哈哈

  • 先获取当前的大盒子box,以及左、右这三个的dom元素,resize
  • 获取到resize 时是一个数组,所以进行了循环遍历,可以不需要这个
  • 鼠标按下时拿到resize的左侧宽度,以及鼠标点击的位置
  • 鼠标移动时获取拖动后的鼠标位置并计算resize[i].left+移动的距离=左边区域最后的宽度------------容器宽度 - 左边区域的宽度 = 右边区域的宽度
  • 你可以设置左侧最小宽度,我在这里设置的是200,你可以拿个变量存储起来便于在父组件更改
  • 拖动时动态设置左侧区域的宽度
  • 鼠标松开时就是注销鼠标事件
dragControllerDiv () {
        let styleLoc = this.styleLoc;
        var resize= document.getElementsByClassName('drag');
        var left = document.getElementsByClassName(styleLoc.left);
        var mid = document.getElementsByClassName(styleLoc.right);
        var box = document.getElementsByClassName(styleLoc.box);
        for (let i = 0; i < resize.length; i++) {
            // 鼠标按下事件
            resize[i].onmousedown = function (e) {
                //颜色改变提醒
                resize[i].style.background = '#818181';
                var startX = e.clientX;
                resize[i].left = resize[i].offsetLeft;
                // 鼠标拖动事件
                document.onmousemove = function (e) {
                    var endX = e.clientX; 
                    var moveLen = resize[i].left + (endX - startX);// (endx-startx)=移动的距离。
                    resize[i].left+移动的距离=左边区域最后的宽度
                    var maxT = box[i].clientWidth - resize[i].offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
                    if (moveLen < 200) moveLen = 200; // 左边区域的最小宽度为32px
                    if (moveLen > maxT - 150) moveLen = maxT - 150; //右边区域最小宽度为150px
                    resize[i].style.left = moveLen; // 设置左侧区域的宽度
                    for (let j = 0; j < left.length; j++) {
                        left[j].style.width = moveLen + 'px';
                        mid[j].style.width = (box[i].clientWidth - moveLen - 10) + 'px';
                    }
                };
                // 鼠标松开事件
                document.onmouseup = function (evt) {
                    //颜色恢复
                    resize[i].style.background = '#d6d6d6';
                    document.onmousemove = null;
                    document.onmouseup = null; 
                   resize[i].releaseCapture && resize[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
                }; 
               resize[i].setCapture && resize[i].setCapture(); //该函数在属于当前线程的指定窗口里设置鼠标捕获
                return false;
            };
        }
    }
},
复制代码

3.样式

大家可以自行修改这个样式

<style lang="scss" scoped >
/*拖拽区div样式*/
.drag{
    cursor: col-resize;
    position: relative;
    top: 300px;
    background-color: #d6d6d6;
    border-radius: 5px;
    margin-top: -10px;
    width: 10px;
    height: 50px;
    line-height: 50px;
    background-size: cover;
    background-position: center;
    font-size: 32px;
    color: white;
}
/*拖拽区鼠标悬停样式*
/.drag:hover {
    color: #444444;
}
</style>
复制代码

完整组件代码

<template>
    <div class="resize" title="收缩侧边栏">⋮</div>
</template>
<script>
export default {
    name: "dragAdjustWidth",
    props: ["styleLoc"],
    data() {
        return {
            screenWidth: document.body.clientWidth
        };
    },
    created() {},
    mounted() {
        this.dragControllerDiv();
        let _this = this; //赋值vue的this
        window.addEventListener("resize", () => {
            this.screenWidth = document.body.clientWidth;
        });
    },
    watch: {
        screenWidth(newVal, oldVal) {
            let styleLoc = this.styleLoc;
            var resize = document.getElementsByClassName("resize");
            var mid = document.getElementsByClassName(styleLoc.right);
            for (let i = 0; i < resize.length; i++) {
                mid[i].style.width = newVal - resize[i].offsetLeft + "px";
            }
        }
    },
    components: {},
    methods: {
        dragControllerDiv() {
            let styleLoc = this.styleLoc;
            var resize = document.getElementsByClassName("resize");
            var left = document.getElementsByClassName(styleLoc.left);
            var mid = document.getElementsByClassName(styleLoc.right);
            var box = document.getElementsByClassName(styleLoc.box);
            let that = this;
            for (let i = 0; i < resize.length; i++) {
                // 鼠标按下事件
                resize[i].onmousedown = function(e) {
                    //颜色改变提醒
                    resize[i].style.background = "#818181";
                    var startX = e.clientX;
                    resize[i].left = resize[i].offsetLeft;
                    that.compatibleStyle(mid[0], "none");
                    // 鼠标拖动事件
                    document.onmousemove = function(e) {
                        var endX = e.clientX;
                        var moveLen = resize[i].left + (endX - startX); // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
                        var maxT = box[i].clientWidth - resize[i].offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
                        if (moveLen < 200) moveLen = 200; // 左边区域的最小宽度为32px
                        if (moveLen > maxT - 150) moveLen = maxT - 150; //右边区域最小宽度为150px
                        resize[i].style.left = moveLen; // 设置左侧区域的宽度

                        for (let j = 0; j < left.length; j++) {
                            left[j].style.width = moveLen + "px";
                            mid[j].style.width =
                                box[i].clientWidth - moveLen - 10 + "px";
                        }
                    };
                    // 鼠标松开事件
                    document.onmouseup = function(evt) {
                        that.compatibleStyle(mid[0], "auto");
                        //颜色恢复
                        resize[i].style.background = "#d6d6d6";
                        document.onmousemove = null;
                        document.onmouseup = null;
                        resize[i].releaseCapture && resize[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
                    };
                    resize[i].setCapture && resize[i].setCapture(); //该函数在属于当前线程的指定窗口里设置鼠标捕获
                    return false;
                };
            }
        },
        compatibleStyle(node, info) {
            if (node.getElementsByTagName("iframe").length) {
                node.getElementsByTagName(
                    "iframe"
                )[0].style.pointerEvents = info;
            }
            if (node.getElementsByTagName("embed").length) {
                node.getElementsByTagName(
                    "embed"
                )[0].style.pointerEvents = info;
            }
        }
    },
    beforeDestroy() {
        window.onresize = null;
    }
};
</script>
<style lang="scss" scoped >
/*拖拽区div样式*/
.resize {
    cursor: col-resize;
    // float: left;
    position: relative;
    top: 300px;
    background-color: #d6d6d6;
    border-radius: 5px;
    margin-top: -10px;
    width: 10px;
    height: 50px;
    line-height: 50px;
    background-size: cover;
    background-position: center;
    /*z-index: 99999;*/
    font-size: 32px;
    color: white;
}
/*拖拽区鼠标悬停样式*/
.resize:hover {
    color: #444444;
}
</style>
复制代码

引用方式

<!-- 大盒子 -->
<div class="catalogTreeContent">
    <div class="leftMenu"></div>
    <DragAdjustWidth :styleLoc="styleLoc"></DragAdjustWidth>
    <div class="rightMenu"></div>
</div>
<script>
// 收缩侧边栏
import DragAdjustWidth from "@/components/page/Common_WEB/dragAdjustWidth";

export default{
    data() {
        return {
            // 收缩侧边栏
            styleLoc: {
                box: "catalogTreeContent",
                left: "leftMenu",
                right: "rightMenu",
            },
        }
    } 
}
</script>
复制代码

我的效果实现表演完了,如果大家看完有啥想问的都可以评论,我会及时回复的。上方如果有问题,欢迎大家提出,我会改正的。

文章分类
前端
文章标签