DesignFormItem.vue 9.13 KB
<template>
  <div class="widget-form-item">
    <div class="widget-mask" @click.capture="handleSelectWidget(index)"></div>
    <div class="drag-widget" title="拖拽" v-if="selectWidget.key == element.key">
      <i class="icon-drag"></i>
    </div>
    <div class="widget-view-action" v-if="selectWidget.key == element.key">
      <i class="icon-copy" title="复制" @click.stop="handleWidgetClone(index)"></i>
      <el-divider direction="vertical"></el-divider>
      <i class="icon-trash" title="删除" @click.stop="handleWidgetDelete(index)"></i>
    </div>
    <ht-form-item
      class="widget-view"
      v-if="element && element.key"
      :class="{active: selectWidget.key == element.key}"
      :label="element.name"
    >
      <template v-if="element.type == 'input'">
        <ht-input
          v-model="element.options.defaultValue"
          :validate="element.options.validate"
          :style="{width: element.options.width}"
          :placeholder="element.options.placeholder"
          :disabled="element.options.disabled"
        />
      </template>

      <template v-if="element.type == 'textarea'">
        <ht-input
          type="textarea"
          :rows="2"
          v-model="element.options.defaultValue"
          :style="{width: element.options.width}"
          :disabled="element.options.disabled"
          :placeholder="element.options.placeholder"
        />
      </template>

      <template v-if="element.type == 'number'">
        <el-input-number
          v-model="element.options.defaultValue"
          :disabled="element.options.disabled"
          :controls-position="element.options.controlsPosition"
          :style="{width: element.options.width}"
        ></el-input-number>
      </template>

      <template v-if="element.type == 'radio'">
        <el-radio-group
          v-model="element.options.defaultValue"
          :style="{width: element.options.width}"
          :disabled="element.options.disabled"
        >
          <el-radio
            :style="{display: element.options.inline ? 'inline-block' : 'block'}"
            :label="item.value"
            v-for="(item, index) in element.options.options"
            :key="item.value + index"
          >{{element.options.showLabel ? item.label : item.value}}</el-radio>
        </el-radio-group>
      </template>

      <template v-if="element.type == 'checkbox'">
        <el-checkbox-group
          v-model="element.options.defaultValue"
          :style="{width: element.options.width}"
          :disabled="element.options.disabled"
        >
          <el-checkbox
            :style="{display: element.options.inline ? 'inline-block' : 'block'}"
            :label="item.value"
            v-for="(item, index) in element.options.options"
            :key="item.value + index"
          >{{element.options.showLabel ? item.label : item.value}}</el-checkbox>
        </el-checkbox-group>
      </template>

      <template v-if="element.type == 'time'">
        <el-time-picker
          v-model="element.options.defaultValue"
          :is-range="element.options.isRange"
          :placeholder="element.options.placeholder"
          :start-placeholder="element.options.startPlaceholder"
          :end-placeholder="element.options.endPlaceholder"
          :readonly="element.options.readonly"
          :disabled="element.options.disabled"
          :editable="element.options.editable"
          :clearable="element.options.clearable"
          :arrowControl="element.options.arrowControl"
          :style="{width: element.options.width}"
        ></el-time-picker>
      </template>

      <template v-if="element.type == 'date'">
        <el-date-picker
          v-model="element.options.defaultValue"
          :type="element.options.type"
          :is-range="element.options.isRange"
          :placeholder="element.options.placeholder"
          :start-placeholder="element.options.startPlaceholder"
          :end-placeholder="element.options.endPlaceholder"
          :readonly="element.options.readonly"
          :disabled="element.options.disabled"
          :editable="element.options.editable"
          :clearable="element.options.clearable"
          :style="{width: element.options.width}"
        ></el-date-picker>
      </template>

      <template v-if="element.type == 'rate'">
        <el-rate
          v-model="element.options.defaultValue"
          :max="element.options.max"
          :disabled="element.options.disabled"
          :allow-half="element.options.allowHalf"
        ></el-rate>
      </template>

      <template v-if="element.type == 'color'">
        <el-color-picker
          v-model="element.options.defaultValue"
          :disabled="element.options.disabled"
          :show-alpha="element.options.showAlpha"
        ></el-color-picker>
      </template>

      <template v-if="element.type == 'select'">
        <el-select
          v-model="element.options.defaultValue"
          :disabled="element.options.disabled"
          :multiple="element.options.multiple"
          :clearable="element.options.clearable"
          :placeholder="element.options.placeholder"
          :style="{width: element.options.width}"
        >
          <el-option
            v-for="item in element.options.options"
            :key="item.value"
            :value="item.value"
            :label="element.options.showLabel?item.label:item.value"
          ></el-option>
        </el-select>
      </template>

      <template v-if="element.type=='switch'">
        <el-switch v-model="element.options.defaultValue" :disabled="element.options.disabled"></el-switch>
      </template>

      <template v-if="element.type=='slider'">
        <el-slider
          v-model="element.options.defaultValue"
          :min="element.options.min"
          :max="element.options.max"
          :disabled="element.options.disabled"
          :step="element.options.step"
          :show-input="element.options.showInput"
          :range="element.options.range"
          :style="{width: element.options.width}"
        ></el-slider>
      </template>

      <template v-if="element.type=='imgupload'">
        <fm-upload
          v-model="element.options.defaultValue"
          :disabled="element.options.disabled"
          :style="{'width': element.options.width}"
          :width="element.options.size.width"
          :height="element.options.size.height"
          token="xxx"
          domain="xxx"
        ></fm-upload>
      </template>

      <template v-if="element.type == 'cascader'">
        <el-cascader
          v-model="element.options.defaultValue"
          :disabled="element.options.disabled"
          :clearable="element.options.clearable"
          :placeholder="element.options.placeholder"
          :style="{width: element.options.width}"
          :options="element.options.remoteOptions"
        ></el-cascader>
      </template>

      <template v-if="element.type == 'editor'">
        <vue-editor v-model="element.options.defaultValue" :style="{width: element.options.width}"></vue-editor>
      </template>

      <template v-if="element.type=='blank'">
        <div
          style="height: 50px;color: #999;background: #eee;line-height:50px;text-align:center;"
        >{{$t('fm.components.fields.blank')}}</div>
      </template>

      <template v-if="element.type == 'text'">
        <span>{{element.options.defaultValue}}</span>
      </template>
    </ht-form-item>
  </div>
</template>

<script>
export default {
  props: ["element", "select", "index", "data"],
  data() {
    return {
      selectWidget: this.select
    };
  },
  mounted() {},
  methods: {
    handleSelectWidget(index) {
      this.selectWidget = this.data.list[index];
    },
    handleWidgetDelete(index) {
      if (this.data.list.length - 1 === index) {
        if (index === 0) {
          this.selectWidget = {};
        } else {
          this.selectWidget = this.data.list[index - 1];
        }
      } else {
        this.selectWidget = this.data.list[index + 1];
      }

      this.$nextTick(() => {
        this.data.list.splice(index, 1);
      });
    },
    handleWidgetClone(index) {
      let cloneData = {
        ...this.data.list[index],
        options: { ...this.data.list[index].options },
        key: Date.parse(new Date()) + "_" + Math.ceil(Math.random() * 99999)
      };

      if (
        this.data.list[index].type === "radio" ||
        this.data.list[index].type === "checkbox" ||
        this.data.list[index].type === "select"
      ) {
        cloneData = {
          ...cloneData,
          options: {
            ...cloneData.options,
            options: cloneData.options.options.map(item => ({ ...item }))
          }
        };
      }

      this.data.list.splice(index, 0, cloneData);

      this.$nextTick(() => {
        this.selectWidget = this.data.list[index + 1];
      });
    }
  },
  watch: {
    select(val) {
      this.selectWidget = val;
    },
    selectWidget: {
      handler(val) {
        this.$emit("update:select", val);
      },
      deep: true
    }
  }
};
</script>
<style lang="scss" scoped>
@import "@/assets/css/form-editor.scss";

div.widget-view {
  padding: 10px 0;
  position: relative;
  overflow: hidden;
}

.widget-view.active {
  outline: 1px solid $--color-primary;
  background: #fefefe;
}
</style>