翼度科技»论坛 编程开发 JavaScript 查看内容

vue3使用vuedraggable和grid实现自定义拖拽布局方式

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
使用vuedraggable和grid实现自定义拖拽布局


实现思路

使用vuedraggable实现拖拽功能,拖拽改变的是模块在list的顺序,使用gird设置动态类名,根据模块在list的位置匹配对应的gird样式。

效果图

每个模块可以拖拽,不同数量和不同位置模块宽度和高度不同(注意:模块样式width:100%,height:100%)

图1-标准布局


图2-三块布局


图3-自定义布局
  1. <template>
  2.   <div class="wrap">
  3.     <div class="flex-row-start defineLayout">
  4.       <div class="flex-row" @click="changeLayout(LayoutType.FOUR)">
  5.         <div class="name">标准布局</div>
  6.       </div>
  7.       <div class="flex-row" @click="changeLayout(LayoutType.THREE)">
  8.         <div class="name">三块布局</div>
  9.       </div>
  10.       <el-dropdown ref="dropdown1" trigger="contextmenu" style="margin-right: 30px">
  11.         <div class="flex-row el-dropdown-link" @click="() => {
  12.           if (dropdown1) dropdown1.handleOpen();
  13.         }">
  14.           <div class="name">自定义布局</div>
  15.         </div>
  16.         <template #dropdown>
  17.           <el-checkbox-group class="flex-col-start" v-model="checkedIdList" :max="4" style="padding: 10px 0 10px 30px;">
  18.             <el-checkbox @change="changeLayout(LayoutType.DEFINE)" v-for="(item, index) of cList" :key="index"
  19.               :label='item.id'>{{
  20.                 item.name }}</el-checkbox>
  21.           </el-checkbox-group>
  22.         </template>
  23.       </el-dropdown>
  24.     </div>
  25.     <div class="draggable-border">
  26.       <draggable :list="moduleList" item-key="id" :options="{ animation: 200, ghostClass: 'ghost' }" :class="{
  27.         gird1col: moduleList.length == 1,
  28.         gird2col: moduleList.length == 2,
  29.         gird3col: moduleList.length == 3,
  30.         gird4col: moduleList.length == 4
  31.       }">
  32.         <template #item="{ element, index }">
  33.           <component :ref="element.ref" :is="element.component" :name="element.name" :class="{
  34.             [`dragItem${index}`]: true,
  35.           }">
  36.           </component>
  37.         </template>
  38.       </draggable>
  39.     </div>
  40.   </div>
  41. </template>
复制代码
  1. <script lang="ts" setup>
  2. import { ref, onMounted } from "vue";
  3. import { useState, useMutations } from "@/utils/useStore";
  4. import Block1 from '@/components/block1/block1';
  5. import Block2 from '@/components/block2/block2';
  6. import Block3 from '@/components/block3/block3';
  7. import Block4 from '@/components/block4/block4';
  8. import Block5 from '@/components/block5/block5.vue';

  9. //@ts-ignore
  10. import draggable from "vuedraggable";
  11. import { LayoutType } from '@/utils/enum';

  12. //资源对象
  13. let resource = ref<any>();
  14. //@ts-ignore
  15. const { moduleList } = useState(["moduleList"], "drag");
  16. //@ts-ignore
  17. const { setModuleList } = useMutations(["setModuleList"], "drag");

  18. let dropdown1 = ref();
  19. let checkedIdList = ref<number[]>([]);//自定义选择的模块

  20. let cList: any[] = [
  21.   {
  22.     type: '1',
  23.     id: 1,
  24.     name: '块1',
  25.     component: Block1
  26.   }, {
  27.     type: '1',
  28.     id: 2,
  29.     name: '块2',
  30.     component: Block2
  31.   }, {
  32.     type: '2',
  33.     id: 3,
  34.     name: '块3',
  35.     component: Block3
  36.   }, {
  37.     type: '2',
  38.     id: 4,
  39.     name: '块4',
  40.     component: Block4
  41.   }, {
  42.     type: '2',
  43.     id: 5,
  44.     name: '块5',
  45.     component: Block5
  46.   },
  47. ];

  48. onMounted(() => {
  49.   setCompontent([1, 2, 3, 4]);
  50. })

  51. // 自定义当前页包含组件
  52. const setCompontent = (idList: number[]) => {
  53.   checkedIdList.value = idList;
  54.   let list = cList.filter((f: any) => {
  55.     return idList.indexOf(f.id) != -1;
  56.   });
  57.   setModuleList(list);
  58.   console.log("list", list);
  59. };

  60. // 切换布局
  61. const changeLayout = (type) => {
  62.   switch (type) {
  63.     case LayoutType.THREE:
  64.       setCompontent([1, 2, 5]);
  65.       break;
  66.     case LayoutType.DEFINE:
  67.       if (checkedIdList.value) setCompontent(checkedIdList.value);
  68.       break;
  69.     default:
  70.       // 默认四宫格
  71.       setCompontent([1, 2, 3, 4]);
  72.       break;
  73.   }
  74. }
  75. </script>
复制代码
  1. <style scoped lang="scss">
  2. .wrap {
  3.   height: 100vh;
  4.   width: 100vw;
  5.   position: relative;
  6.   display: block;
  7.   overflow: hidden;

  8.   .defineLayout {
  9.     color: #fff;
  10.     height: 41px;
  11.     width: 100%;
  12.     background-color: #000;
  13.     align-items: center;
  14.     padding: 0 20px;

  15.     .name {
  16.       font-size: 12px;
  17.       font-weight: 500;
  18.       color: #FFFFFF;
  19.       line-height: 17px;
  20.       margin-left: 5px;
  21.       margin-right: 20px;
  22.       cursor: pointer;
  23.     }
  24.   }

  25.   .draggable-border {
  26.     background-color: #fff;
  27.     width: 100%;
  28.     height: calc(100vh - 41px);
  29.   }
  30. }

  31. // 设置拖拽组件的样式
  32. .draggable-border>div {
  33.   width: 100%;
  34.   height: 100%;
  35.   display: grid;
  36.   grid:
  37.     'one two'
  38.     'three four';
  39.   grid-template-columns: 50% 50%;
  40.   grid-template-rows: 50% 50%;
  41. }

  42. .gird4col {
  43.   grid:
  44.     'one two'
  45.     'three four' !important;
  46.   grid-template-columns: 50% 50% !important;
  47.   grid-template-rows: 50% 50% !important;
  48. }

  49. .gird3col {
  50.   grid:
  51.     'one three'
  52.     'two three' !important;
  53.   grid-template-columns: 50% 50% !important;
  54.   grid-template-rows: 50% 50% !important;
  55. }

  56. .gird2col {
  57.   grid:
  58.     'one two'
  59.     'one two' !important;
  60.   grid-template-columns: 50% 50% !important;
  61.   grid-template-rows: 50% 50% !important;
  62. }

  63. .gird1col {
  64.   grid:
  65.     'one' !important;
  66.   grid-template-columns: 100% !important;
  67.   grid-template-rows: 100% !important;
  68. }

  69. .fullscreen {
  70.   width: 100vw;
  71.   height: 100vh;
  72.   position: fixed;
  73.   top: 0;
  74.   left: 0;
  75.   z-index: 999;
  76. }

  77. .dragItem0 {
  78.   grid-area: one;
  79. }

  80. .dragItem1 {
  81.   grid-area: two;
  82. }

  83. .dragItem2 {
  84.   grid-area: three;
  85. }

  86. .dragItem3 {
  87.   grid-area: four;
  88. }
  89. </style>
复制代码
总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

来源:https://www.jb51.net/javascript/322357h1m.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具