这是一个综合使用案例,需求是页面引入动态的模块,可以自定义编辑数量和排序。

效果图:

 该项目依element,同时为了动态效果,我引入了Vue.Draggable插件,以及vue的动画组<transition-group>

贴上页面代码

<template>
  <div class="dashboard-container">
    <el-row :gutter="15">
      <draggable element="ul" v-model="cardList" :options="options">
        <transition-group name="fade">
          <el-col v-for="(item, index) in cardList" :key="item.id" :span="item.span">
            <component :is="item.name" :idx="index" @closeThisCard="close"></component>
          </el-col>
        </transition-group>
      </draggable>
    </el-row>
  </div>
</template>

<script>
import draggable from 'vuedraggable'
import { Building, Ceshi, EnergyDashboard, EnergyMonitor, KpiAnalysis, PowerConsumption, UnprocessedAlarm } from './components'

export default {
  components: {
    draggable,
    Building,
    Ceshi,
    EnergyDashboard,
    EnergyMonitor,
    KpiAnalysis,
    PowerConsumption,
    UnprocessedAlarm
  },
  data () {
    return {
      cardList: [
        {id: 1, span: 8, name: 'building'},
        {id: 2, span: 8, name: 'ceshi'},
        {id: 3, span: 8, name: 'energy-dashboard'},
        {id: 4, span: 16, name: 'energy-monitor'},
        {id: 5, span: 8, name: 'kpi-analysis'},
        {id: 6, span: 8, name: 'power-consumption'},
        {id: 7, span: 16, name: 'unprocessed-alarm'}
      ],
      options: {
        animation: 500,
        handle: '.el-card__header'
      }
    }
  },
  methods: {
    close (e) {
      this.cardList.splice(e, 1)
    },
    add () {
      this.cardList.push(
        {id: 8, span: 24, name: 'building'}
      )
    }
  }
}
</script>

<style lang="scss" scoped>
.dashboard-container{
  position: relative;
  .module{
    position: absolute;
    z-index: 99;
    width: 60px;
    height: 24px;
    top: -9px;
    right: 0px;
  }
}
.el-row{
  height: 932px;
  .el-col{
    margin-bottom: 16px;
  }
}
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}
</style>

以及组件核心代码:

<template>
  <el-card class="wz-card">
    <div slot="header">
      <div class="head-left">
        <h3>xxxxceshi</h3>
        <span>xxx</span>
        <el-switch v-model="showOther" active-color="rgba(103, 121, 143, 0.2)" inactive-color="rgba(103, 121, 143, 0.2)"></el-switch>
      </div>
      <div class="head-right">
        <el-dropdown trigger="click" @command="cardOrder">
          <span class="el-dropdown-link">
            #{{idx}}#
            <i class="iconfont icon-card-more"></i>
          </span>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="refresh">刷新</el-dropdown-item>
            <el-dropdown-item command="close">移除</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </div>
    </div>
  </el-card>
</template>

<script>
export default {
  props: ['idx'],
  data () {
    return {
      showOther: false
    }
  },
  methods: {
    cardOrder (order) {
      if (order === 'close') {
        this.closeThisCard(this.idx)
      }
    },
    closeThisCard (index) {
      this.$emit('closeThisCard', index)
    }
  }
}
</script>

首先动态渲染页面模块,并不是说用jsp的思路从后台拿代码。

这里的方案是,所有基本模块前端都有写,通过模块引入全部引入到当前页面,然后使用cardList数组模拟需要渲染的模块。

其中span表示该模块宽度,name表示模块名字。结合element的flex布局和vue的动态组件(is)就可以动态渲染出想要的有宽度和顺序的模块组。

最后是拖拽排序和动态删除(增加的话暂时没写)。

拖拽排序的话直接用Vue.Draggable插件,这里的话我只加了两个属性,一个是动画时间和拖拽块(animation,handle)。

这个插件非常简单,可以直接点击查看使用方法。拖拽效果ok,绑定cardList数组后拖拽能改变顺序。

然后是删除,我做的是模块内控制删除,使用了父子组件传值的方法。传过去的是idx,返回$emit的closeThisCard方法。通过删除cardList中值的方法动态删除。

 

Logo

前往低代码交流专区

更多推荐