1. 程式人生 > >vue元件動態引入

vue元件動態引入

這是一個綜合使用案例,需求是頁面引入動態的模組,可以自定義編輯數量和排序。

效果圖:

 該專案依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中值的方法動態刪除。