vue3拖拽布局+动态组件+自适应布局

这篇具有很好参考价值的文章主要介绍了vue3拖拽布局+动态组件+自适应布局。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.拖拽布局插件

Vue Grid Layout -️ 适用Vue.js的栅格布局系统可拖动和可调整大小栅格布局的Vue组件。https://jbaysolutions.github.io/vue-grid-layout/zh/

//在package.json中dependencies下添加下面插件库,并执行命令npm install

 "vue-grid-layout": "^3.0.0-beta1",

 2.拖拽页面代码

<template>
  <div>
    <!-- 
        colNum: 定义栅格系统的列数,其值需为自然数.
        rowHeight:每行的高度,单位像素。
        isDraggable:标识栅格中的元素是否可拖拽.
        isResizable:标识栅格中的元素是否可调整大小。
        isMirrored:标识栅格中的元素是否可镜像反转。
        autoSize:标识容器是否自动调整大小
        verticalCompact:标识布局是否垂直压缩。
        preventCollision:防止碰撞属性,值设置为ture时,栅格只能拖动至空白处。
        useCssTransforms:标识是否使用CSS属性 transition-property: transform;
        responsive:标识布局是否为响应式
    -->
    <grid-layout :layout="layout"
                 :col-num="12"
                 :row-height="30"
                 :is-draggable="true"
                 :is-resizable="true"
                 :vertical-compact="true"
                 :margin="[10, 10]"
                 :use-css-transforms="true"
                 @layout-updated="layoutUpdatedEvent">
      <grid-item v-for="(item,index) in layout"
                 :x="item.x"
                 :y="item.y"
                 :w="item.w"
                 :h="item.h"
                 :i="item.i"
                 :key="item.i"
                 @move="moveEvent"
                 @resized="resizedEvent"
                 style="background:pink;">
        <keep-alive>
          <component :is="item.name"
                     :ref="`dragRef${index}`"
                     :key="item.name+index"
                     :id="item.name+index"
                     :width="item.Wpx"
                     :height="item.Hpx"></component>
        </keep-alive>
      </grid-item>
    </grid-layout>
  </div>
</template>
<script lang="ts">
import { BarChart, FunnelChart, PieChart, RadarChart } from './components';

export default {
  components: {
    BarChart,
    FunnelChart,
    PieChart,
    RadarChart
  }
};
</script>
<script setup lang="ts">
const layout = ref([
  { x: 0, y: 0, w: 2, h: 2, i: '0' },
  { x: 2, y: 0, w: 2, h: 4, i: '1' },
  { x: 4, y: 0, w: 2, h: 5, i: '2' },
  { x: 6, y: 0, w: 2, h: 3, i: '3' },
  { x: 8, y: 0, w: 2, h: 3, i: '4' },
  { x: 10, y: 0, w: 2, h: 3, i: '5' }
]);

const testLayout = [
  {
    x: 0,
    y: 0,
    w: 2,
    h: 8,
    i: '0',
    name: 'BarChart'
  },
  //   {
  //     x: 2,
  //     y: 0,
  //     w: 2,
  //     h: 8,
  //     i: '1',
  //     name: 'FunnelChart'
  //   },
  //   {
  //     x: 4,
  //     y: 0,
  //     w: 2,
  //     h: 8,
  //     i: '2',
  //     name: 'PieChart'
  //   },
  //   {
  //     x: 6,
  //     y: 0,
  //     w: 2,
  //     h: 8,
  //     i: '3',
  //     name: 'RadarChart'
  //   },
  {
    x: 8,
    y: 0,
    w: 2,
    h: 8,
    i: '4',
    name: 'BarChart'
  }
];
layout.value = testLayout;

//更新事件(布局更新或栅格元素的位置重新计算)
const layoutUpdatedEvent = (newLayout: any) => {
  console.log('布局更新了');
  console.log('Updated layout: ', newLayout);
  layout.value = newLayout;
  console.log(layout.value);
};
//移动时的事件
const moveEvent = (i: any, newX: any, newY: any) => {
  console.log('盒子移动了');
  console.log('MOVE i=' + i + ', X=' + newX + ', Y=' + newY);
};
//调整大小后的事件
/**
 *
 * @param i the item id/index
 * @param newH new height in grid rows
 * @param newW new width in grid columns
 * @param newHPx new height in pixels
 * @param newWPx new width in pixels
 *
 */
const resizedEvent = (
  i: any,
  newH: any,
  newW: any,
  newHPx: any,
  newWPx: any
) => {
  console.log('改变了尺寸');
  console.log(
    'RESIZED i=' +
      i +
      ', H=' +
      newH +
      ', W=' +
      newW +
      ', H(px)=' +
      newHPx +
      ', W(px)=' +
      newWPx
  );
  let newLayouts = layout.value.map(item => {
    console.log(item);
    console.log(item.i == i);

    if (item.i == i) {
      item.Wpx = newWPx + 'px';
      item.Hpx = newHPx + 'px';
    }
    return item;
  });
  layout.value = newLayouts;
};
</script>


<style scoped>
</style>

3.图表子组件代码文章来源地址https://www.toymoban.com/news/detail-513438.html

<template>
  <div class="box">
    <div :id="id"
         :class="className"
         :style="{ height, width }" />
  </div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts';

const props = defineProps({
  id: {
    type: String,
    default: 'barChart'
  },
  className: {
    type: String,
    default: ''
  },
  width: {
    type: String,
    default: '100%',
    required: true
  },
  height: {
    type: String,
    default: '100%',
    required: true
  }
});
const options = {
  grid: {
    left: '2%',
    right: '2%',
    // top: '5%',
    bottom: '10%',
    containLabel: true
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross',
      crossStyle: {
        color: '#999'
      }
    }
  },
  legend: {
    x: 'center',
    y: 'bottom',
    data: ['收入', '毛利润', '收入增长率', '利润增长率'],
    textStyle: {
      color: '#999'
    }
  },
  xAxis: [
    {
      type: 'category',
      data: ['浙江', '北京', '上海', '广东', '深圳'],
      axisPointer: {
        type: 'shadow'
      }
    }
  ],
  yAxis: [
    {
      type: 'value',
      min: 0,
      max: 10000,
      interval: 2000,
      axisLabel: {
        formatter: '{value} '
      }
    },
    {
      type: 'value',
      min: 0,
      max: 100,
      interval: 20,
      axisLabel: {
        formatter: '{value}%'
      }
    }
  ],
  series: [
    {
      name: '收入',
      type: 'bar',
      data: [7000, 7100, 7200, 7300, 7400],
      barWidth: 20,
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#83bff6' },
          { offset: 0.5, color: '#188df0' },
          { offset: 1, color: '#188df0' }
        ])
      }
    },
    {
      name: '毛利润',
      type: 'bar',
      data: [8000, 8200, 8400, 8600, 8800],
      barWidth: 20,
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#25d73c' },
          { offset: 0.5, color: '#1bc23d' },
          { offset: 1, color: '#179e61' }
        ])
      }
    },
    {
      name: '收入增长率',
      type: 'line',
      yAxisIndex: 1,
      data: [60, 65, 70, 75, 80],
      itemStyle: {
        color: '#67C23A'
      }
    },
    {
      name: '利润增长率',
      type: 'line',
      yAxisIndex: 1,
      data: [70, 75, 80, 85, 90],
      itemStyle: {
        color: '#409EFF'
      }
    }
  ]
};
const initEcharts = () => {
  console.log('123');
  echarts.init(document.getElementById(props.id) as HTMLDivElement).dispose(); //先销毁

  // 图表初始化
  var chart = echarts.init(document.getElementById(props.id) as HTMLDivElement);

  chart.setOption(options);

  // 大小自适应
  setTimeout(() => {
    //由于网格布局拖拽放大缩小图表不能自适应,这里设置一个定时器使得echart加载为一个异步过程
    console.log('111');
    chart.resize();
  }, 0);
};

watch(
  () => props,
  (newVal, oldVal) => {
    console.log('监听传值', newVal);
    initEcharts();
  },
  {
    deep: true
  }
);

onMounted(() => {
  console.log('图表初始化');
  initEcharts();
});
</script>
<style lang="scss" scoped>
.box {
  width: 100%;
  height: 100%;
  background: #fff;
}
</style>

到了这里,关于vue3拖拽布局+动态组件+自适应布局的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3实现组件可拖拽 vuedraggable

    npm i -S vuedraggable@next 中文文档,里面有完整代码案例,值得一看 vue.draggable vue3 版本在工作台中的应用场景 - itxst.com

    2024年02月13日
    浏览(37)
  • 简单使用vue拖拽组件vue3-dnd

    项目中需要使用到拖拽,这里使用vue3-dnd来满足需求 这里项目使用的vue3(使用js而非ts) 插件官网地址:Vue3 DnD 安装 然后在app.vue里面添加代码  通过DndProvider组件为项目提供拖拽功能  概念 项目item和类型:被拖拽的对象我们称呼为某种类型的项目,类型的作用是让放置目标

    2023年04月13日
    浏览(44)
  • vue3项目中引入dialog插件,支持最大最小化、还原、拖拽

    效果图:  上图是layui-vue组件库中的layer插件,我的项目使用的是element-plus组件库,在用不上layui组件库的情况下,就单独引入 @layui/layer-vue 这个弹层插件就可以了 npm地址:@layui/layer-vue - npm layui-vue组件库地址:Layui - Vue 前端 UI 框架  使用方式: 1.按照npm地址的Readme操作,在

    2024年02月14日
    浏览(43)
  • 记录--Vue3问题:如何实现组件拖拽实时预览功能?

    实现一个CMS内容管理系统,在后台进行内容编辑,在官网更新展示内容。 关于后台的编辑功能,大致分为两部分: 组件拖拽预览 、 组件内容编辑实时预览 。 对于组件拖拽预览,用户可以在含有各种功能组件的列表中,选择需要的组件进行拖拽。将组件拖拽到预览画布中后

    2024年02月04日
    浏览(43)
  • vue3使用拖拽组件draggable.next的使用教程【保姆级】

    环境:vue3+setup语法 首先放官方文档的链接: 中文版本: vue.draggable.next 中文文档 - itxst.com (民间翻译) 英文版本:GitHub - SortableJS/vue.draggable.next: Vue 3 compatible drag-and-drop component based on Sortable.js 因为自己写的过程中,官方文档和网上的资料都非常不明,使用版本各不相同,极

    2024年02月01日
    浏览(40)
  • vue3如何实现使用SortableJs插件进行表格内的数据项拖拽排序

    npm i sortablejs --save 或者 yarn add sortablejs   我使用的组件库是ant design vue, 我主要使用的是Sortablejs 中的结束拖拽之后的onEnd 属性,因为是单表格的简单拖拽排序所以只用到了自带的参数对象evt的oldIndex和newIndex这两个属性,分别表示被拖拽的数据项拖拽前的下标和拖拽完成之后

    2024年02月11日
    浏览(51)
  • vue2&vue3 el-table实现整行拖拽排序功能(使用sortablejs插件)

    Vue3组件地址 Vue2组件地址 Vue2基于ElementUi再次封装基础组件文档 vue3+ts基于Element-plus再次封装基础组件文档

    2024年02月08日
    浏览(56)
  • 记录--Vue3基于Grid布局简单实现一个瀑布流组件

    在学习Grid布局之时,我发现其是CSS中的一种强大的布局方案,它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局,在刷某书和某宝首页时,我们发现其展示方式就是一种瀑布流,是一种流行的网站页面布局,视觉表现为参差不齐的多栏布局,随着页

    2024年02月05日
    浏览(61)
  • vue3 动态加载组件、动态引入组件

    1.问题 在做一个用 vite 构建的 vue3 项目时,动态拉取导入 .vue 页面,然后控制台一直有以下提示,页面也无法渲染出来。 2.分析 根据上面的报错提示,让我们安装并使用: @rollup/plugin-dynamic-import-vars 这个插件(最终没有这个方案)。 Vite官方文档说 需要使用Glob 导入形式 ,然

    2023年04月09日
    浏览(85)
  • vue3 动态组件和异步组件

    当使用 component :is=\\\"...\\\" 来在多个组件间作切换时,被切换掉的组件会被卸载。我们可以通过 KeepAlive组件强制被切换掉的组件仍然保持“存活”的状态。

    2024年02月08日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包