gridstack.js+组件(eharts/element-ui等)(第二章)

一、回顾上期

        通过上一期了解gridstack.js的了解,我们已经知道了怎么去下载插件,并运用gridstack插件实现可拖动、可调整大小、响应式引导友好的布局;知道了一些画布的设置和事件的监听,知道了在this.grid.addWidget( {w: 2, h: 2, content: '添加'})中设置文字、图片等;

二、结合原理

        但是当你想要往grid-stack-item里面放入你自己写好的组件;或者嵌入报告、表格、折线图等复杂的组件时,你会想到怎么做?

        这里提供的方法就是:1.拿到组件;2.设置组件的参数;3.把组件放进去;

1.结合步骤

1.拿到组件---注册局部组件,引入组件,使用let GirdComponent = Vue.component('A', A)

2.设置组件的参数---使用new创造一个实例对象,我们就可以new GirdComponent({})在其中设置组件的参数;

3.把组件放进去---通过原生js的appendChild(),把组件放入你想放入的grid-stack-item中;

三、实现过程

<template>
  <div id="home">
    <!-- 左边的添加与删除 -->
    <div class="left-box">
      <div class="delete-grid">放在这里删除小部件!</div>
      <div class="add-grid" draggable="true">把我拖进仪表盘!</div>
    </div>

    <!-- 右边的grid容器 -->
    <div class="right-box">
      <div class="grid-stack"></div>
    </div>
  </div>
</template>
<script>
// 引入gridstack
import "gridstack/dist/gridstack.min.css";
import { GridStack } from "gridstack";
import Vue from "vue";
import barChart from "../EchartsView/EchartsView.vue";

export default {
  name: "APP",
  data() {
    return {
      grid: null,
      option: {
        xAxis: {
          type: "category",
          data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
          itemStyle: { color: "red" },
        },
        yAxis: {
          type: "value",
        },
        series: [
          {
            data: [120, 200, 150, 80, 70, 110, 130],
            type: "bar",
            showBackground: true,
            backgroundStyle: {
              color: "#BBFFFF",
            },
            itemStyle: {
              color: "#EEE9E9",
              borderWidth: 1,
              borderColor: "#000000",
            },
          },
        ],
        aria: {
          enable: true,
          decal: {
            show: true,
            decals: {
              symbol: "rect",
              dashArrayX: [2, 0],
              dashArrayY: [2, 2],
              rotation: 0.523,
              color: "#ffffff",
              border: 1,
            },
          },
        },
      },
    };
  },
  created() {},
  mounted() {
    this.GridStackInit();
    let container = document.querySelector(".right-box");
    container.ondragover = function (e) {
      e.preventDefault();
    };
    container.addEventListener("drop", (e) => {
      this.addGrid();
    });
    let deleteGrid = document.querySelector(".delete-grid");
    deleteGrid.ondragover = function (e) {
      e.preventDefault();
    };
    deleteGrid.addEventListener("drop", (e) => {});
  },
  methods: {
    GridStackInit() {
      let Options = {
        dragOut: true,
        margin: 5, //网格里面之间的距离
        acceptWidgets: true, //接受从其他网格或外部拖动的小部件
        dragIn: ".add-grid",
      };
      // let item7 = document.getElementsByClassName('grid-stack-item7')
      this.grid = GridStack.init(Options);
      let gridData = [
        { w: 4, h: 2, content: "1" },
        {
          w: 4,
          h: 4,
          content: "不能缩放,也不能移动!",
          noResize: true,
          noMove: true,
        },
        { w: 2, h: 2, content: "不能缩放!", noResize: true },
        { w: 2, h: 2, content: "4" },
        { w: 2, h: 2, content: "5" },
        { w: 2, h: 4, content: "6" },
        { w: 4, h: 2, content: "7" },
        { w: 2, h: 2, content: "8" },
        { w: 6, h: 4, id: "card_9" },
        { w: 2, h: 2, content: "10" },
        { w: 2, h: 2, content: "11" },
      ];
      this.grid.load(gridData);
      if (this.grid.engine) {
        this.grid.engine.nodes.forEach((widget) => {
          this.loadGridItem(widget);
        });
      }
    },
    addGrid() {
      this.grid.addWidget({ w: 2, h: 2, content: "添加" });
    },
    loadGridItem(widget) {
      // 把组件仿佛第九个方块中
      if (widget.id == "card_9") {
        // 找到第九个方块
        let widgetEl = widget.el;
        let content = widgetEl.querySelector(".grid-stack-item-content");

        let itemDom = document.createElement("div");
        itemDom.setAttribute("id", "card_" + widget._id);

        // 把组件放入方块中
        content.appendChild(itemDom);

        // 局部注册组件,组件放入方块中
        let WidgetComponent = Vue.component("barChart", barChart);
        let instance = new WidgetComponent({
          el: "#card_" + widget._id,
          propsData: { name: "xiaoming" },
          parent: this,
        });
        // 调整大小,echarts图resize
        this.grid.on('resizestop', function(event, gridEl) {
        // 当你缩放暂停,触发条件,重新绘图resize
        instance.handleResize()
        })
      }
    },
  },
};
</script>
<style lang="scss" scoped>
#home {
  display: flex;
  width: 100vw;
  background-color: #44a1ee;
  margin: 20px;
}
.left-box {
  display: inline;
  display: flex;
  flex-direction: column;
  width: 20%;
  border-right: 2px dashed #ffffff;
  .delete-grid {
    width: 80%;
    height: 120px;
    background-color: #ee6d44;
    border: 2px solid #ffffff;
    margin: 20px 0 20px 20px;
  }
  .add-grid {
    width: 80%;
    height: 120px;
    background-color: #54ff9f;
    border: 2px solid #ffffff;
    margin: 0 0 0 20px;
  }
}
.right-box {
  width: 70%;
  border: 2px solid #ffffff;
  margin: 20px 0 20px 20px;
}
</style>
<style lang="scss">
.grid-stack-item-content {
  background-color: #ffffff;
  text-align: center;
}
</style>

最后的效果就是这样:我已经把组件放入到了grid-stack-item-content,你需要放入什么组件;局部注册组件,然后根据条件放入其中即可;

四、小结

1.当你想放入不同的组件时

 这个遍历出来的widget就是上面的gridData,可以在对象里面加入不同组件的标识type;或者加入接口的参数,当在下面loadGridItem中执行的时候,拿到数据,画出图形;

2.resize重绘

关键事件:grid.on('resizestop',function(event: Event,el: GridItemHTMLElement){});------调整大小结束

(1)当里面是echarts时,触发事件;重绘

(1)当里面是其他组件时,响应式布局;

3.滚动加载

原理就是:滚动的时候触发grid-item,计算每个grid-item的距离(距离上边框、宽度、高度、页面的高度等);

条件:

1.grid-item的高度 > 页面高度;gird-item的顶部或者底部在可是范围内

1.grid-item的高度 < 页面高度;gird-item的顶部和者底部在可是范围内

//监听容器的滚动:得到容器的滚动高度
let gardStackContent = this.$refs.gridStack
gardStackContent.addEventListener('scroll', this.scrollLoad())

//遍历this.grid.engine.nodes:得到grid-item的距离顶部距离和自身高度
let girdItemTop = widget.el.offsetTop
let girdItemBottom = widget.el.offsetTop + widget.el.offsetHeight

let scrollH = scrollTop

4.拖入位置

这里有一个问题,暂时还没有最好的解决办法---替代办法;

1.现在从外面托人一个进来,触发事件,往里面添加一个grid-item

2.但是使用addWidget()始终会放在最后面,因为你没有给这个grid-item,x与y

3.那么在添加的过程中就要计算x 与 y 的位置 和 你鼠标落点位置的关系;

        可以看第一期里面从外面拖进来的时候,下面是有一个阴影,然后拖到哪里阴影跟随;上面这个方法暂时做不到这个效果,上一期使用的是clone

        缺点就是这里仍然要设置w和h,clone下面的阴影也是根据这个来的;你拖动的是单个的可以实现,如果你拖动的是一个菜单或者多个,展示还没有想到好的办法;有办法解决可留言!!!

五、推荐

        这个使用girdStack.ja的人比较少,在网上找到Vue Grid Layout -️ 适用Vue.js的栅格布局系统,两个用法相差不大;但是这个用的人比较多,官网教学详细,建议使用这个。

官网:Vue Grid Layout -️ 适用Vue.js的栅格布局系统

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值