首页 > 其他分享 >vue+element实现拖拽分屏

vue+element实现拖拽分屏

时间:2022-11-15 11:12:20浏览次数:66  
标签:... vue rightAsideWidth 鼠标 element background vuex resize 分屏

实现效果:使用鼠标点击分割线拖动,可实现左右展示框宽度(也可修改为高度)的变化,如下图

1、封装组件

首先需要封装按钮点击的这条线,计算鼠标点击后滑动的距离:

<template>
  <div ref="rightResize" class="right-resize">
    <i ref="rightResizeBar">...</i>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        rightAsideWidth: 300,
      }
    },
    mounted() {
      this.dragChangeRightAsideWidth();
    },
    methods: {
      dragChangeRightAsideWidth() {
	// 保留this引用
	let resize = this.$refs.rightResize;
	let resizeBar = this.$refs.rightResizeBar;
	resize.onmousedown = e => {   // 鼠标按下执行的方法
	  let startX = e.clientX;  // 记录赋值横坐标起始位置
	  // 鼠标按下颜色改变
	  resize.style.background = "#ccc";
	  resizeBar.style.background = "#aaa";
	  resize.left = resize.offsetLeft;  // 记录距离父辈元素左边缘的距离
	  document.onmousemove = e2 => {  // 鼠标移动执行的方法
	    // 计算并应用位移量
	    let endX = e2.clientX;  // 记录赋值横坐标结束的位置
	    let moveLen = startX - endX;   // 计算鼠标拖动之间的位移差
            // 如果向右拖动且最大不超过1000px,或者向左拖动且做小不小于50px ,则执行里面的方法
	    if ((moveLen < 0 && this.rightAsideWidth < 1000) || (moveLen > 0 && this.rightAsideWidth > 50)) {
	      startX = endX;  // 当前值赋值给初始值
	      this.rightAsideWidth -= moveLen;   // 侧边的宽度加(减)上拖动后的位移量,就是此时的宽度
	      if (this.rightAsideWidth < 50) {   // 设置最小宽度
		this.rightAsideWidth = 50;
	      }
	      this.$emit('input', this.rightAsideWidth);   // 需要执行的方法,可不写
              this.$emit('change', this.rightAsideWidth);// 宽度改变后 需要把宽度传给父组件
	    }
	  };
	  document.onmouseup = () => {  // 鼠标松开,样式复原
	    // 颜色恢复
	    resize.style.background = "#fafafa";
	    resizeBar.style.background = "#ccc";
	    document.onmousemove = null;
	    document.onmouseup = null;
	  };
	  return false;
        };
      }
    }
  };
</script>

<style scoped>
  .right-resize {
    width: 5px;
    height: 100%;
    cursor: w-resize;
    background: #fafafa;
  }
  .right-resize i {
    margin-top: 300px;
    width: 5px;
    height: 35px;
    display: inline-block;
    word-wrap: break-word;
    word-break: break-all;
    line-height: 8px;
    border-radius: 5px;
    background: #ccc;
    color: #888;
  }
</style>

2、父组件引用

<template>
    <div class="global-layout-vue">	
        <el-container>
            // rightAsideWidth 宽度可变化
            <el-aside v-show="leftCollapse" :style="{ width: rightAsideWidth + 'px' }"> 
		...		
            </el-aside>
	    <RightResize v-model="rightAsideWidth" @change="rightAsideWidthChange" v-show="leftCollapse"></RightResize>
            <el-main v-if="activeName == 'two'" style="padding: 0;border-left: 1px solid #dcdfe6; background-color: #eee;" class="see_main">
		...		
	    </el-main>
        </el-container>
    </div>
</template>
<script>
  export default {
        data() {
            return {
              rightAsideWidth: 300,
            }
        },
        methods: {
          rightAsideWidthChange(width) {
	      this.$store.commit('global/setRightAsideWidth', width);
          },
        }
  }
</script>

3、vuex

基础用法可参照:vuex的基础用法
1、store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import global from './modules/global'
import createPersistedState from "vuex-persistedstate"  // vuex持久化(需要安装差价插件)
Vue.use(Vuex);

export default new Vuex.Store({
    state() {
        return {
           ...
        }
        getters: {
          ...
        },
        mutations: {
          ...
        },
        modules: {
          global,
        },
        plugins: [createPersistedState({  // vuex持久化用到的参数
          storage: window.sessionStorage,
          reducer(val) {
            return val // 刷新时返回全部的vuex储存的参数
          }
        })]
});

1、store/modules/global.js

export default {
  namespaced: true,
  state: {
    rightAsideWidth: 0,
  },
  mutations: {
    setRightAsideWidth(state, rightAsideWidth) {
      state.rightAsideWidth = rightAsideWidth;
    },
  }
}

标签:...,vue,rightAsideWidth,鼠标,element,background,vuex,resize,分屏
From: https://www.cnblogs.com/axingya/p/16891556.html

相关文章

  • Vue 拦截器思路
    //数据响应拦截器,统一处理返回的数据逻辑axios.interceptors.response.use(res=>{if(res&&res.status==HTTP_STATUS.SUCCESS){returnres.data;}els......
  • 【Vue3】本地没问题,部署后 public 下的某些资源 404 不能访问
    如果你本地没问题,线上访问出现404,你得看看你public下面得资源文件夹命名是不是和.gitignore下得配置文件冲突了,我就是命名为dist导致直接被忽略了,重新改了个名字后......
  • vuecli作用域插槽
    <template><divid="app"class="container"><Categorytitle="美食"><templatescope="{games}"><ul><liv-for="(g,inde......
  • vue源码分析-基础的数据代理检测
    简单回顾一下这个系列的前两节,前两节花了大量的篇幅介绍了Vue的选项合并,选项合并是Vue实例初始化的开始,Vue为开发者提供了丰富的选项配置,而每个选项都严格规定了合并的策......
  • vue源码分析-挂载流程和模板编译
    前面几节我们从newVue创建实例开始,介绍了创建实例时执行初始化流程中的重要两步,配置选项的资源合并,以及响应式系统的核心思想,数据代理。在合并章节,我们对Vue丰富的选项......
  • vue源码分析-响应式系统工作原理
    上一章,我们讲到了Vue初始化做的一些操作,那么我们这一章来讲一个Vue核心概念响应式系统。我们先来看一下官方对深入响应式系统的解释:当你把一个普通的JavaScript对象传......
  • vue中的ajax
    vue中的ajaxvue脚手架配置代理方法一​ 在vue.config.js中添加如下配置:devServer:{proxy:"http://localhost:5000"}说明:优点:配置简单,请求资源时直接发给前端(80......
  • Vuex 数据持久化(vuex-persistedstate)
    使用conststore=newVuex.Store({modules:{user:{},},getters,actions,//异步mutations,//同步plugins:[createPersistedState({......
  • vue cli 下载 node_modules
    cd至项目文件根目录npminstall用npm安装有可能会到导致关联失败解决方案yarninstall安装yarnyarn安装第三方库比npm会快一些npminstallyarn-g如果M......
  • Vue 子组件调用父组件方法[不参数版]
    子组件<template><div><button@click="childEvent()">点击调父组件方法</button></div></template><script>exportdefault{methods:{......