都好久没有更新了 最新在做一个关于低代码拖拽搭建实现大屏应用的项目 以下是一些关于其中的核心点以及我在过程中遇到的问题 希望能帮助到正在攻克这块的程序员们

基础页面大概就是这样 拖拽是基于vue-draggable-resizable(vue2) 插件做的 但是这个插件有升版


vue-draggable-resizable-gorkys (新增冲突检测 和 辅助线功能) 推荐大家下载新版有新增的功能

GitHub - gorkys/vue-draggable-resizable-gorkys: Vue 用于可调整大小和可拖动元素的组件并支持冲突检测、元素吸附、元素对齐、辅助线

这是属性地址 

基 本 - 基 本 组 件 ⋅ Storybook (tingtas.com) 这个是在线演示的项目
基础下载和基础属性大家去主页面自己看下 比较简单
我主要讲下中间过程中遇到的坑 (大家使用这个代码肯定是用来开发低代码平台 然后我列出的问题肯定是大家使用这个插件遇到的问题)

1.选中组件时调整他的属性样式 点击右侧面板 他的选中状态消失了

目前我的功能是他选中点击 右边红框区域显示他的属性和信息 然后可以修改他 但是使用这个插件点击其他区域他的选中状态会消失
1.解决方案
 

 <vue-draggable-resizable
              class="draggable-item"
              :w="item.width"
              :h="item.height"
              :x="item.position.x"
              :y="item.position.y"
              :z="item.index"
              :snap="true"
              :snap-tolerance="20"
              @dragging="onDrag"
              @dragstop="dragStop"
              @resizing="onResize"
              @resizestop="onResizeStop"
              @activated="onActivated(item, item.type)"
              @deactivated="onDeactivated"
              :prevent-deactivation="true"
              :parent="false"
              v-for="(item, index) in dataList"
              :key="index"
                //新添加了一标识 让其标识等于唯一值时选中
              :active="selectComponentId == item.identifier"

              :style="{ display: item.hideStatus == true ? 'none' : 'block' }"
              :draggable="item.lockStatus"
              :resizable="item.lockStatus"
              :ref="`draggable${item.identifier}`"
              @click="
                draggableClickFn(
                  item.position.x,
                  item.position.y,
                  item.width,
                  item.height
                )
              "
            >
//因为他的选中样式只有那个几个勺匙 我加了一个淡绿色的透明背景 突出选中样式
            <img
                class="lineImg"
                v-show="selectComponentId == item.identifier"
                src="../../../../assets/images/liner-bgc.png"
                alt=""
                @contextmenu.prevent="showContextMenu($event, item)"
              />

</vue-draggable-resizable>



//然后在点击事件时将其唯一值赋予它
 onActivated(data, type) {
   that.selectComponentId = data.identifier;
  },



 // 监听画布外点击事件
    handleKeepActive(e) {
      let that = this;
      const target = e.target || e.srcElement;
      if (that.$refs.canvasRef.contains(target)) {
        that.isPreventDeActive = true;
        // console.log('在区域内');
        that.selectComponentId = null;
        this.$emit("update:selectComponentId", this.selectComponentId);
      } else {
        that.isPreventDeActive = false;
        // console.log('在区域外');
      }
      return false;
    },

我监听画布完区域 清除其选中状态 点击其他区域他的选中状态不清除(这样就可以设置他的样式) 

 2. 画布缩放后他的拖拽位置发生偏差 拖拽不动 
大家可以看到我右下角有缩放按钮 他的画布是可以缩放的 然后他的拖拽位置会受到缩放元素 他的拖拽位置会发生偏差  (这里只提供我的解决方法 大家有新的方法可以解决也可以私聊我 感谢)

   //新加一个点击事件 他的onActivated 事件只会在未选中时选中后只会触发一次 我们需要获取他的每次初始位置
draggableClickFn(x, y, w, h) {
      this.dragStartX = x;
      this.dragStartY = y;
    },
   //拖拽中
    onDrag: function (x, y) {
      if (this.selectComponentId) {
        const item = this.dataList.find(
          (item) => item.identifier == this.selectComponentId
        );
        if (item) {
          let scale = this.scale;
          if (!this.dragStartX && !this.dragStartY) {
            // 第一次拖拽时记录初始位置
            this.dragStartX = x;
            this.dragStartY = y;
          }
//计算逻辑
          const diffX = x - this.dragStartX;
          const diffY = y - this.dragStartY;
          this.newX = Math.floor(diffX / this.scale + item.position.x);
          this.newY = Math.floor(diffY / this.scale + item.position.y);
//这里要获取到当前的元素 因为只设置他的位置值时 虽然x y数值动了 但是他的元素本身没有设置
          // let element = this.$refs.draggableRef;
          const refName = `draggable${this.selectComponentId}`;
          let element = this.$refs[refName][0];
          element.style.transform = `translate(${this.newX}px, ${this.newY}px)`;
        }
      }
      // console.log(this.dataList, 'dataList');
    },
//拖拽结束
    dragStop(x, y) {
      if (this.selectComponentId) {
        const item = this.dataList.find(
          (item) => item.identifier == this.selectComponentId
        );
        if (item) {
//拖拽结合后直接将数值赋予到当前的组件中
          item.position.x = this.newX;
          item.position.y = this.newY;
          this.dragStartX = null;
          this.dragStartY = null;
          this.$emit("update:dataList", this.dataList);
        }
      }
    },

3.他的大小拉伸也会受到偏移的影响 但是我使用上面的拖拽时相同的方法时 会出现问题等我完整解决后在分享给大家 大家有好的解决方法也可以私信我 感谢

 大概复杂的就只有这几点 我可能讲解的不仔细 但是这个是提供给在深入了解这个插件做项目的小伙伴 初了解的小伙伴 可以去插件主页面了解一下吧
大家还有其他问题就跟我说 我看我使用过程中还有没有碰到类似的

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐