本地上传、封装组件

95 阅读1分钟

手写本地上传

<template>
  <div class="upload-img">
    <ul class="img-list"
      v-if="fileArray.length">
      <li v-for="(item, index) in fileArray"
        :key="index"
        class="imgShowList">
        <img :src="item"
          class="imgShowImg"
          :style="{width: '20px', height: '20px'}">
        <i class="el-icon-close imgShowClose"
          @click.stop="deleteImg(index)"></i>
      </li>
    </ul>
    <label :for="name"
      v-if="fileArray.length < limit"
      class="upload-label"
      :class="{'notAllow': isMax}">
      <i class="el-icon-plus"></i>
      <input type="file"
        :id="name"
        class="upload-input"
        @change="inputChange"
        :disabled="isMax">
    </label>
    <slot></slot>
    <div class="prevBox"
      ref="prevBox"></div>
  </div>
</template>

<script>
import { uploadApi } from '@/api/processTemplate'
import { deepClone } from '@/utils/index.js'

export default {
  name: 'UploadIcon',
  data () {
    return {
      fileArray: [],
      // imgStyle: {},
      limit: 1,
      // type: 'png'
      type: ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'] // 支持上传的图片类型
    }
  },
  computed: {
    isMax () {
      return this.fileArray.length >= this.limit
    }
  },
  methods: {
    deleteImg (index) {
      this.fileArray.splice(index, 1)
      this.$emit('input', deepClone(this.fileArray))
      this.$emit('fileChange')
    },
    async inputChange (e) {
      if (this.fileArray.length >= this.limit) return
      const file = e.target.files[0]
      const data = new FormData()
      data.append('uploadFile', file)
      if (!this.type.includes(file.type) && !this.cancelCheckType) {
        this.$message.error('请上传 .jpg 或 .jpeg 或 .png 或 .gif 格式的图片!')
        return
      }
      const result = await this.getFileImgProperty(file)
      if ((result.width === this.width && result.height === this.height) || (this.width === 'auto' && this.height === 'auto')) {
        const data = new FormData()
        data.append('uploadFile', file)
        const res = await uploadApi(data).catch(e => { console.log(e) })
        if (res && res.code === 0) {
          this.fileArray.push(res.data)
          this.$emit('input', deepClone(this.fileArray))
          this.$emit('fileChange')
        } else {
          this.$message.error('上传失败!')
        }
      } else {
        this.$message.error(`请上传${this.width}px宽,${this.height}px高的图片`)
      }
    },
    getFileImgProperty (file) {
      if (!(file instanceof Blob)) return Promise.reject(new Error('格式错误'))
      return new Promise((resolve, reject) => {
        const img = document.createElement('img')
        img.classList.add('prevImg')
        img.file = file
        this.$refs.prevBox.appendChild(img)
        const reader = new FileReader()
        reader.addEventListener('load', function () {
          img.src = reader.result
        }, false)
        reader.readAsDataURL(file)
        img.onload = () => {
          const styles = window.getComputedStyle(img, null)
          const imgStyle = {
            width: parseInt(styles.width),
            height: parseInt(styles.height)
          }
          this.$refs.prevBox.removeChild(img)
          resolve(imgStyle)
        }
        img.onerror = () => {
          reject(new Error('图片加载失败!'))
        }
      })
    }
  }
</script>

<style lang="scss" scoped>
</style>

表格封装

  <el-table :data="list"
    highlight-current-row
    @selection-change="selectionChange"
    @cell-mouse-enter="cellMouseEnter"
    @cell-mouse-leave="cellMouseLeave"
    @cell-click="rowClick"
    :height="height">
    <el-table-column v-if="selectionDisplay" type="selection" width="55"></el-table-column>
    <el-table-column v-for="item in columns"
        :key="item.key"
        :label="item.label"
        :align="item.align"
        :formatter="item.formatter"
        :show-overflow-tooltip="item.showTooltip"
        :width="item.width&&item.width">
      <template slot-scope="scope">
        <a v-if="item.isClick"
           class="link-type"
           @click="viewDetails(scope.row)">{{scope.row[item.key]}}</a>
           <!-- 输入框 -->
        <div v-else-if="item.text" class="edit-text">
          <el-input v-model="scope.row[item.key]" :ref='scope.row.id'></el-input>
        </div>
        <div v-else-if="item.type === 'img'">
          <img :src="scope.row.imgUrl" class="table-img">
        </div>
        <span class="formatSpanData" :title="formatData(scope.row,item)" v-else>{{formatData(scope.row,item)}}</span>
        <!-- 自定义配置插槽 -->
        <slot v-if="item.isCustom" name="custom" :scope="scope"></slot>
        <!-- 操作按钮插槽,使用时可接收slot-scope="{scope}" -->
        <slot v-if="item.isHandleBtn" name="handle" :scope="scope">
          <!-- 默认按钮是用在更新公告和灰度管理页面的 -->
          <el-button :type="'primary'"
                     v-if="item.chilid[0].showBtn"
                     @click="onHandle('publish',scope.row)">编辑</el-button>
          <el-button :type="+scope.row.status===0?'info':'danger-text'"
                     :disabled="+scope.row.status===0"
                     v-if="item.chilid[1].showBtn"
                     @click="onHandle('stop',scope.row)">权限</el-button>
        </slot>
      </template>
    </el-table-column>
  </el-table>

表单封装

<!--  表头条件搜素
      <meal-search-filter
      :query.sync="filterInfo.query"
      :filter-list="filterInfo.list"
      :list-type-info="listTypeInfo"
      @handleClick="handleClick">
      <template v-slot:form-test>
        自定义插槽
      </template>
    </meal-search-filter>
    type input/输入框 select/选择框  time/时间选择框  date/日期选择框
    { type: 'slot', label: ' 插槽', value: 'test' },
     <template v-slot:botton>按钮插槽</template>
-->
  <div class="page-filter bg-white">
    <el-form
      ref="ruleFilter"
      :model="query"
      :label-width="labelWidth"
      class="from-filter">
      <div class="filter-content">
        <el-form-item
          v-for="(item, index) in getConfigList()"
          :key="index"
          :prop="item.value"
          :label="item.label"
          :class="item.className">
          <!-- solt -->
          <template v-if="item.type === 'slot'">
            <slot :name="'form-' + item.value" />
          </template>
          <!-- 输入框 -->
          <el-input
            v-if="item.type === 'input'"
            v-model="searchQuery[item.value]"
            :class="`filter-${item.type}`"
            :type="item.type"
            :disabled="item.disabled"
            :clearable="item.clearable === false ? item.clearable : true"
            :placeholder="item.placeholder || getPlaceholder(item)"
            @focus="handleEvent(item.event)"/>
          <!--区间-->
          <template v-if="item.type === 'section'">
            <div class="from-section">
              <el-input v-model="searchQuery[item.min]" class="margin-right-20" @blur="blurNum(item, 1)"/>~
              <el-input v-model="searchQuery[item.max]" class="margin-left-20" @blur="blurNum(item, 2)"/>
            </div>
          </template>
          <!-- 搜素选择框 -->
          <el-select
            :editable="false"
            v-if="item.type === 'selectSearch'"
            v-model="searchQuery[item.value]"
            :class="`filter-${item.type}`"
            :disabled="item.disabled"
            :clearable="item.clearable === false ? item.clearable : true"
            :placeholder="item.placeholder || getPlaceholder(item)"
            :multiple="item.multiple || false"
            :defaultFirstOption="item.defaultFirstOption || false"
            :filterable="item.filterable || false"
            :remote="item.remote || false"
            :remote-method="(query) => { remoteMethod(query, item)}"
            @change="handleEventSelect"
            @focus="handleEvent(item.event)">
            <el-option
              v-for="(childItem) in listTypeInfo[item.list]"
              :key="childItem.value"
              :label="childItem.label"
              :value="childItem"/>
          </el-select>
          <!-- 选择框 -->
          <el-select
            :editable="false"
            v-if="item.type === 'select'"
            v-model="searchQuery[item.value]"
            :class="`filter-${item.type}`"
            :disabled="item.disabled"
            :clearable="item.clearable === false ? item.clearable : true"
            :filterable="item.filterable === false ? item.filterable : true"
            :placeholder="item.placeholder || getPlaceholder(item)"
            @change="handleEventSelect($event, item)">
          <el-option
            v-for="(childItem, childIndex) in listTypeInfo[item.list]"
            :key="childIndex"
            :label="childItem.label"
            :value="childItem.value"/>
          </el-select>
          <!-- 下拉树 -->
          <el-select
            v-if="item.type === 'selectTree'"
            v-model="searchQuery[item.value]"
            class="filter-select-tree"
            :ref="`selectTree${item.value}`"
            :name="item.name"
            :clearable="item.clearable === false ? item.clearable : true"
            :filterable="item.filterable === false ? item.filterable : true"
            :placeholder="item.placeholder || getPlaceholder(item)">
            <el-option class="select-tree-li" :value="searchQuery[item.value]" :label="selectTree[item.value]"  :style="{ minWidth: '190px', height: 'auto', backgroundColor:'#fff' }">
              <el-tree
                :data="listTypeInfo[item.list]"
                :defaultProps="defaultProps"
                @node-click="handleNodeClick"></el-tree>
            </el-option>
          </el-select>
          <!-- 时间选择框 -->
          <el-time-select
            v-if="item.type === 'time'"
            v-model="searchQuery[item.value]"
            :class="`filter-${item.type}`"
            :picker-options="item.TimePickerOptions"
            :clearable="item.clearable === false ? item.clearable : true"
            :disabled="item.disabled"
            :placeholder="item.placeholder || getPlaceholder(item)"/>
          <!-- 日期选择框 -->
          <el-date-picker
            v-if="item.type === 'date'"
            v-model="searchQuery[item.value]"
            :class="`filter-${item.type}`"
            :picker-options="item.datePickerOptions || datePickerOptions"
            :type="item.dateType"
            :clearable="item.clearable === false ? item.clearable : true"
            :disabled="item.disabled"
            :placeholder="item.placeholder || getPlaceholder(item)"
            :value-format="item.valueFormat || 'yyyy-MM-dd HH:mm:ss'"
            @focus="handleEvent(item.event)"
          />
          <!--时间范围选择-->
          <el-date-picker
            v-if="item.type === 'datetime'"
            v-model="searchQuery[item.value]"
            :class="`filter-${item.type}`"
            :range-separator="item.rangeSeparator || '-'"
            :start-placeholder="item.startPlaceholder || '开始时间'"
            :end-placeholder="item.endPlaceholder || '结束时间'"
            :type="item.dateType"
            :picker-options="item.TimePickerOptions"
            :clearable="item.clearable"
            :disabled="item.disabled"
            :readonly="item.readonly"
            :size="item.size"
            :align="item.align"
            :value-format="item.valueFormat || 'yyyy-MM-dd HH:mm:ss'"
            :popper-class="item.popperClass"
            :default-time="item.defaultTime"
            :placeholder="item.placeholder || getPlaceholder(item)"
            @change="handleEvent"/>
        </el-form-item>
      </div>
      <div class="filter-btn" v-if="!isShowMeal">
        <el-form-item>
          <slot name="botton"></slot>
          <el-button size="mini" type="primary" @click="handleChange('select')" v-show="isSureVisible">查询</el-button>
          <el-button size="mini" @click="resetForm('ruleFilter')" v-show="isResetVisible">重置</el-button>
        </el-form-item>
      </div>
    </el-form>
  </div>