手写本地上传
<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: [],
limit: 1,
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 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">
<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>