封装了通用表格,通用查询组,按钮组,模态框
组件使用基于json配置,需要自己设计的ui很少,举例模态框,就封装了通用组件二十个左右,包括输入框,下拉框,日期框,开关,数字框,密码框…
模态框组件代码展示
FormDialog.vue
<template>
<section class="form-dialog-container">
<el-dialog
v-loading="loading"
:title="title"
height="80%"
:width="width"
:close-on-click-modal="false"
:visible.sync="dialogVisible"
:append-to-body="appendToBody"
:before-close="handleClose"
:custom-class="customClass"
@opened="opened"
@open="open"
@closed="closed"
>
<el-form
ref="form"
:model="form"
:rules="rules"
:label-width="labelWidth"
label-suffix=":"
>
<input type="password" style="position: absolute;z-index: -1;width:0;opacity:0;">
<input type="text" style="position: absolute;z-index: -1;width:0;opacity:0;">
<template v-for="(item, index) in formItems">
<transition :key="index" name="fade" mode="out-in">
<!-- 是否隐藏 -->
<div v-if="hiddenFn(item,form)" class="form-item-wrap">
<!-- 放置文字 -->
<div
v-if="item.type === 'place'"
:style="item.style||{paddingLeft:item.labelWidth||'100px'}"
>
<span>{{ item.text }}</span>
</div>
<!-- 注意文字 : 注意:xxx-->
<div
v-if="item.type === 'careful'"
class="careful-txt"
>
<label
v-if="item.label"
class="careful-label"
>{{ item.label }}</label>
<span>{{ item.text }}</span>
</div>
<!-- 警告 -->
<el-form-item
v-else-if="item.type === 'warning'"
label-width="0"
>
<el-alert
:title="item.text"
type="warning"
show-icon
:closable="false"
/>
</el-form-item>
<!-- 单选 -->
<el-form-item
v-else-if="item.type === 'radio'"
:key="index"
:label="item.label"
:prop="item.prop"
class="mini-height"
>
<el-radio-group v-model="form[item.prop]">
<el-radio
v-for="(option, index) in (item.options instanceof Array ? item.options : (options[item.options] || []))"
:key="index"
:label="option[item.optionValue || 'value']"
>{{
option[item.optionLabel || 'label']
}}
<jee-popover v-if="option.popoverText" style="margin-left:8px" v-bind="option" />
</el-radio>
</el-radio-group>
<div v-if="item.explain" class="gray">{{ item.explain }}</div>
</el-form-item>
<!-- 多选框 -->
<el-form-item
v-else-if="item.type === 'checkbox'"
:key="index"
:label="item.label"
:label-width="item.labelWidth"
:prop="item.prop"
class="mini-height"
>
<el-checkbox
v-if="item.complex"
v-model="form[item.prop]"
class="t-check"
v-bind="item"
:disabled="item.disabled"
:true-label="item.optionValue||1"
:false-label="item.defaultValue||0"
@change="selectChange"
>
{{ item.optionLabel }}
</el-checkbox>
<el-checkbox-group v-else v-model="form[item.prop]">
<el-checkbox
v-for="(option, index) in (item.options instanceof Array ? item.options : (options[item.options] || []))"
:key="index"
:class="item.class"
:label="option[item.optionValue || 'value']"
>{{ option[item.optionLabel || 'label'] }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<!-- 带标题-线框多选组 -->
<el-form-item
v-else-if="item.type === 'sharebox'"
:label-width="item.labelWidth||'0px'"
:prop="item.prop"
class=" mini-height check-share"
>
<div class="check-share-label">
<label class="check-share-title">{{ item.title }}</label>
<el-link
:key="index"
:underline="false"
@click="handleAdd($event,item)"
>
<jee-icon
:icon-class="item.linkIcon||'jia1'"
class="jee-hover-fill link-icon"
/>
{{ item.linkName || '增加' }}
</el-link>
</div>
<el-checkbox-group v-model="form[item.prop]">
<el-checkbox
v-for="(option, index) in (item.options instanceof Array ? item.options : (options[item.options] || []))"
:key="index"
:label="option[item.optionValue || 'value']"
>
{{ option[item.optionLabel || 'label'] }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<!-- 树形单选标签(后) -->
<el-form-item
v-else-if="item.type==='selectTree'"
:label-width="item.labelWidth||'0px'"
class="tag-wrap"
:prop="item.prop"
:label="item.labelWidth?item.label:''"
>
<label v-show="item.label&&!item.labelWidth" class="tree-box-label">
<span class="t-red title-label">*</span>{{ item.label }}:</label>
<div class="tree-box scrollbar">
<el-tree
:data="(item.options instanceof Array ? item.options : (options[item.options] || []))"
node-key="id"
default-expand-all
:expand-on-click-node="false"
>
<span
slot-scope="{ node, data }"
style="width:100%"
:class="{'is-disabled':data.disabled}"
@click="getRadioId(data,item)"
>
<span>{{ data.name || data[item.optionsLabel] }}</span>
<span
class="right-radio"
>
<el-radio
v-if="form[item.prop] === data.id"
v-model="form[item.prop]"
:label="data.id || data[item.optionsValue]"
/>
</span>
</span>
</el-tree>
</div>
</el-form-item>
<!-- 树形多选标签(前) -->
<el-form-item
v-else-if="item.type === 'checkTree'"
:key="index"
:label="item.label"
:prop="item.prop"
:label-width="item.labelWidth||'0px'"
>
<div
:style="{width:item.width||'300px',maxHeight:scrollHight+'px',height:item.height}"
class="check-tree-wrap scrollbar"
>
<el-tree
:ref="'startTree'+item.prop"
v-bind="item"
show-checkbox
:default-checked-keys="form[item.prop]"
:data="item.tree"
:node-key="item.nodeKey||'id'"
:check-strictly="item.checkStrictly"
default-expand-all
@check="handleCheckChange"
@check-change="handleCheckKeys(item)"
>
<span slot-scope="{ node, data }" :style="data.style||{}">
<span :class="{'is-disabled':data.disabled}">{{ data[item.props.label || 'label'] }}</span>
</span>
</el-tree>
</div>
</el-form-item>
<!-- 树形多选标签(后) -->
<el-form-item
v-else-if="item.type==='selectTrees'"
label-width="0"
:prop="item.prop"
class="el-form-item tag-wrap"
>
<div class="label-box">
<el-tag
v-for="tag in orgTag"
:key="tag.id"
class="tag-item"
closable
:disable-transitions="false"
@close="handleTagClose(tag,item)"
>
{{ tag.name }}
</el-tag>
</div>
<div class="tree-box scrollbar">
<!-- <el-checkbox-group v-model="form[item.prop]"> -->
<el-tree
:data="(item.tree instanceof Array ? item.tree : (options[item.tree] || []))"
node-key="id"
default-expand-all
:expand-on-click-node="false"
>
<span
slot-scope="{ node, data }"
style="width:100%"
@click="getCheckId(data,item)"
>
<span>{{ data.name }}</span>
<span class="right-radio">
<el-checkbox
v-if="form[item.prop].indexOf(data.id)>-1"
:checked="true"
/>
</span>
</span>
</el-tree>
<!-- </el-checkbox-group> -->
</div>
</el-form-item>
<!-- 单选框组(列表) -->
<el-form-item
v-else-if="item.type === 'radioGroup'"
:label="item.label"
:prop="item.prop"
v-bind="item"
class="mini-height"
>
<radio-group v-model="form[item.prop]" v-bind="item" />
</el-form-item>
<!-- 单选框组(列表) -->
<el-form-item
v-else-if="item.type === 'checkList'"
:label="item.label"
:prop="item.prop"
v-bind="item"
class="mini-height"
>
<check-list v-model="form[item.prop]" v-bind="item" />
</el-form-item>
<!-- 开关 -->
<el-form-item
v-else-if="item.type === 'switch'"
:key="index"
:label="item.label"
:prop="item.prop"
class="mini-height"
>
<el-switch
v-model="form[item.prop]"
:disabled="item.disabled"
:active-value="item.activeValue||true"
:inactive-value="item.inactiveValue||false"
/>
<span
class="switch-text jee-font-hover"
:class="{'jee-font-second-light': form[item.prop]}"
>{{
form[item.prop] ? (item.enableText || '启用') : (item.disableText || '禁用')
}}</span>
</el-form-item>
<!-- 计数器 -->
<el-form-item
v-else-if="item.type === 'inputNum'"
:key="index"
:label="item.label"
:prop="item.prop"
class="small-height"
>
<el-input-number
v-model.number="form[item.prop]"
size="small"
:min="item.min||item.min===0?0:1"
:max="item.max||10"
@change="handleChange($event)"
/>
<div v-if="item.explain" class="gray">{{ item.explain }}</div>
</el-form-item>
<!-- 选择框 -->
<el-form-item
v-show="!item.showByFormKey||form[item.showByFormKey]===item.showByFormValue"
v-else-if="item.type === 'select'&&(item.show===undefined||item.show)"
:key="index"
:label="item.label"
:prop="item.prop"
:style="item.style"
>
<el-select
v-model="form[item.prop]"
size="small"
popper-class="jee-border"
:multiple="item.multiple||false"
:collapse-tags="item.collapseTags||false"
:disabled="item.disabled"
v-bind="item"
:placeholder="item.placeholder"
@change="change(item)"
>
<el-option
v-for="option in (item.options instanceof Array ? item.options : (options[item.options] || []))"
:key="option[item.optionValue || 'value']"
:label="option[item.optionLabel || 'label']"
:value="option[item.optionValue || 'value']"
:disabled="option[item.optionDisabled || 'disabled']"
/>
</el-select>
<el-button
v-if="item.btnsText"
type="primary"
:style="'width:'+(item.width||'68px')"
size="small"
class="jee-bg-light-important"
@click="handleBtns($event)"
>{{ item.btnsText }}
</el-button>
<div v-if="item.explain" class="gray">{{ item.explain }}</div>
</el-form-item>
<!-- 级联选择器 -->
<el-form-item
v-else-if="item.type === 'cascader'"
:key="index"
:label="item.label"
:prop="item.prop"
>
<el-cascader
ref="cascader"
v-model="form[item.prop]"
size="small"
popper-class="jee-border"
v-bind="item"
:options="(item.options instanceof Array ? item.options : (options[item.options] || []))"
:props="getCascaderProps(item)"
:show-all-levels="false"
clearable
@change="handleChangeCascader(item,form[item.prop])"
/>
<div v-if="item.explain" class="gray">{{ item.explain }}</div>
</el-form-item>
<!-- 纯文本 -->
<el-form-item
v-else-if="item.type==='text'"
:key="index"
:label="item.label"
class="mini-height"
>
<span :style="{color:item.textColor||'#333333'}">{{ form[item.prop] }}</span>
</el-form-item>
<!-- 日期时间 -->
<el-form-item
v-else-if="item.type==='time'"
:key="index"
:label="item.label"
class="mini-height"
>
<span>{{ $moment(form[item.prop], item.format) }}</span>
</el-form-item>
<!-- 时间选择器 -->
<el-form-item
v-else-if="item.type === 'timePicker'"
:key="index"
v-bind="item"
:label="item.label"
>
<el-date-picker
v-model="form[item.prop]"
style="width:300px"
v-bind="item"
size="small"
:type="item.timeType||'datetime'"
:placeholder="item.placeholder"
:start-placeholder="item.startText||'开始时间'"
:end-placeholder="item.endText||'结束时间'"
:value-format="item.format||'yyyy-MM-dd HH:mm:ss'"
:picker-options="item.pickerOptions"
/>
<div v-if="item.explain" class="gray">{{ item.explain }}</div>
</el-form-item>
<!-- 多行输入框 -->
<el-form-item
v-else-if="item.type==='textarea'"
:key="index"
v-bind="item"
:label="item.label"
>
<el-input
v-model="form[item.prop]"
type="textarea"
v-bind="item"
:style="{height: item.height ? item.height : '32px'}"
:autosize="item.autosize?item.autosize:{ minRows: 1 }"
size="small"
:placeholder="item.placeholder"
:show-word-limit="item.showWordLimit?item.showWordLimit:''"
/>
<div v-if="item.explain" class="gray">{{ item.explain }}</div>
</el-form-item>
<!-- 密码输入框 -->
<el-form-item
v-else-if="item.type === 'password'"
:key="index"
v-bind="item"
:label="item.label"
>
<el-input
v-model="form[item.prop]"
autocomplete="new-password"
type="password"
size="small"
v-bind="item"
:placeholder="item.placeholder"
:disabled="item.disabled"
>
<el-button
v-if="item.appendText"
slot="append"
:style="'width:'+(item.width||'68px')"
size="small"
class="jee-bg-light-important"
@click="handleAppend($event)"
>{{ item.appendText }}
</el-button>
</el-input>
<div v-if="item.explain" class="gray">{{ item.explain }}</div>
</el-form-item>
<!-- 输入框 -->
<el-form-item
v-show="!item.showByFormKey||form[item.showByFormKey]===item.showByFormValue"
v-else-if="!item.type"
:key="index"
v-bind="item"
:style="item.style"
:label="item.label"
>
<el-input
v-model="form[item.prop]"
autocomplete="new-password"
size="small"
v-bind="item"
:placeholder="item.placeholder"
:disabled="item.disabled||formDisabled"
@blur="blur(item.prop)"
>
<el-button
v-if="item.appendText"
slot="append"
:style="'width:'+(item.width||'68px')"
size="small"
class="jee-bg-light-important"
@click="handleAppend($event)"
>{{ item.appendText }}
</el-button>
</el-input>
<div v-if="item.explain" class="gray">{{ item.explain }}</div>
</el-form-item>
<!-- 选择上传 -->
<el-form-item
v-else-if="item.type === 'upload'"
:key="index"
v-bind="item"
:label="item.label"
>
<el-input v-model="form[item.prop]" :type="item.type||''" size="small" v-bind="item">
<div slot="append">
<el-upload
ref="upload"
:style="'width:'+(item.width||'68px')"
multiple
:show-file-list="false"
:file-list="form.fileList"
:action="item.action||''"
:on-remove="handleRemove"
:on-change="beforeUpload"
:auto-upload="false"
>
<el-button
v-if="item.appendText"
slot="trigger"
:style="'width:'+(item.width||'68px')"
size="small"
class="jee-bg-light-important"
>{{ item.appendText }}
</el-button>
</el-upload>
</div>
</el-input>
<div v-if="item.explain" class="gray">{{ item.explain }}</div>
</el-form-item>
<!-- 图片裁剪上传 -->
<el-form-item
v-else-if="item.type === 'imageUpload'"
:key="index"
:prop="item.prop"
:class="item.class"
:label="item.label"
>
<jee-image-upload
v-model="form[item.prop]"
v-bind="item.option"
:default-url="form[item.urlProp]"
/>
</el-form-item>
<!-- 自定义,通过插槽传入 -->
<el-form-item
v-show="!item.showByFormKey||form[item.showByFormKey]===item.showByFormValue"
v-else-if="item.type === 'slot'"
:key="index"
:label="item.label"
:prop="item.prop"
v-bind="item"
:class="item.class"
>
<slot :name="item.prop" :form="form" :item="item" />
<div
v-if="item.explain"
:style="item.explainWidth?'width:'+item.explainWidth:'width:414px'"
class="gray"
>{{ item.explain }}
</div>
</el-form-item>
<!-- 按钮(上传) -->
<el-form-item
v-show="!item.showByFormKey||form[item.showByFormKey]===item.showByFormValue"
v-else-if="item.type === 'btn'"
:key="index"
v-bind="item"
:label="item.label"
>
<div v-if="item.btnType === 'Upload'">
<el-upload
ref="uploadBtn"
:style="'width:'+(item.width||'68px')"
:file-list="item.fileList"
:show-file-list="true"
:action="item.action||''"
:before-remove="handleBeforeRemove"
:on-change="handleBtnUpload"
:auto-upload="false"
>
<el-button
type="primary"
size="small"
class="jee-bg-light-important"
>{{ item.btnText }}
</el-button>
</el-upload>
<div class="upload-btn-txt">
<span>{{ item.name }}</span>
</div>
</div>
<el-button
v-else
type="primary"
size="small"
@click="handleBtn(item,$event)"
>{{ item.btnText }}
</el-button>
<div v-if="item.explain" :style="item.explainStyle" class="gray">{{ item.explain }}</div>
</el-form-item>
</div>
</transition>
</template>
</el-form>
<slot />
<span v-if="showFoot" slot="footer" class="dialog-footer">
<span v-if="footText" class="foot-text">{{ footText }}</span>
<el-button v-if="showCancel" size="small" plain @click="handleCancel">{{ '取消' }}</el-button>
<el-button
v-for="(item, index) in buttons"
:key="index"
type="primary"
size="small"
:disabled="(typeof item.disabled === 'function')?item.disabled():item.disabled"
@click="handleConfirm(item)"
>{{ item.text }}
</el-button>
</span>
</el-dialog>
</section>
</template>
<script>
import radioGroup from '@/components/myComponents/mixins/radioGroup'
import checkList from '@/components/myComponents/mixins/checkList'
export default {
name: 'FormDialog',
mixins: [radioGroup, checkList],
props: {
// 禁用表单输入框,用于详情查看状态切换
formDisabled: {
type: Boolean,
default: false
},
loading: {
type: Boolean,
default: false
},
width: {
type: String,
default: '600px'
},
title: {
type: String,
default: 'global.create'
},
footText: {
type: String,
default: ''
},
scrollHight: {
type: Number,
default: document.documentElement.scrollHeight * 56 / 100
},
showCancel: {
type: Boolean,
default: true
},
showFoot: {
type: Boolean,
default: true
},
buttons: {
type: Array,
default() {
return [
// {保存继续新建默认不开启
// text: 'global.saveAndContinue',
// type: 'Submit',
// keepAlive: true
// },
{
text: '保存',
type: 'Submit'
}
]
}
},
form: {
type: Object,
default: () => ({})
},
rules: {
type: Object,
default: () => ({})
},
formItems: {
type: Array,
default: () => []
},
labelWidth: {
type: String,
default: '166px'
},
options: {
type: Object,
default: () => ({})
},
appendToBody: {
type: Boolean,
default: false
},
handleClose: {
type: Function,
default: (done) => {
done()
}
},
customClass: {
type: String,
default: ''
}
},
data() {
return {
dialogVisible: false,
orgTag: []
}
},
methods: {
opened() {
this.$emit('opened')
},
open() {
this.$emit('open')
},
closed() {
this.$emit('closed')
},
selectChange() {
this.$emit('change')
},
blur(item) {
this.$emit('inpBlur' + item)
},
// 树形多选框
getCheckId(data, item) {
var i = this.form[item.prop].indexOf(data.id)
if (i > -1) {
this.form[item.prop].splice(i, 1)
this.orgTag.splice(i, 1)
} else {
this.form[item.prop].push(data.id)
this.orgTag.push(data)
}
},
handleTagClose(tag, item) {
var i = this.form[item.prop].indexOf(tag.id)
this.form[item.prop].splice(i, 1)
this.orgTag.splice(i, 1)
},
getOrgKey(ids, item) {
// console.log(item.tree.map(v => ids.indexOf(v.id) > -1))
// return item.find(v => ids.indexOf(v.id) > -1)
},
// 树形单选框
getRadioId(data, item) {
if (!data.disabled) {
if (item.onlySelectLeaf) {
if (!(data.children instanceof Array && data.children.length)) {
this.form[item.prop] = data.id
}
} else {
this.form[item.prop] = data.id
}
}
},
showDialog() {
this.dialogVisible = true
this.$nextTick(() => {
this.$refs.form.clearValidate()
})
},
handleCancel() {
const that = this
const done = function() {
that.$refs.form.resetFields()
that.$refs.form.clearValidate()
that.dialogVisible = false
}
this.handleClose(done)
this.$emit('handleCancel')
},
handleAppend(e) {
this.$emit('handleAppend', e)
},
handleBtns(e) {
this.$emit('handleBtns', e)
},
handleBtn(data, e) {
this.$emit(`handleBtn${data.btnType}`, data, e)
},
handleRemove(file) {
this.$emit('handleRemove', file)
},
handleBeforeRemove(file) {
this.$emit('handleBeforeRemove', file)
return this.$confirm('确定删除' + file.name + '?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
},
handleBtnUpload(file, fileList) {
var type = this.uploadType(file)
this.$emit('handleBtnUpload', file, type)
},
// 上传-选择文件
beforeUpload(file, fileList) {
var type = this.uploadType(file)
var list = fileList.map(v => {
v.type = this.uploadType(v)
return v
})
this.$emit('beforeUpload', file, type, list)
},
// 上传-文件类型
uploadType(file) {
var type = file.raw.type
var i = type.indexOf('/')
var suffix = type.slice(0, i)
var fileType = ''
// File文件 Flash Flash Image图片 Media视频 Audio音频 为空则默认Image
switch (suffix) {
case 'image':
fileType = ''
break
case 'text':
fileType = 'File'
break
case 'application':
fileType = 'File'
break
case 'video':
fileType = 'Media'
break
case 'audio':
fileType = 'Audio'
break
default:
fileType = ''
break
}
return fileType
},
handleChange(e) {
this.$emit('handleChange', e)
},
// 添加组织数据到列表
handleAdd(e, item) {
const data = Object.assign({}, this.form)
this.$emit(`handleAdd${item.addType}`, data, item)
},
handleConfirm(btn) {
const data = Object.assign({}, this.form)
this.$refs.form.validate(valid => {
if (valid) {
if (!btn.keepAlive) {
this.dialogVisible = false
}
if (btn.type === 'Submit') {
if (!btn.reset) {
this.$refs.form.resetFields()
}
this.$emit('handleConfirm', data, btn)
} else {
if (!btn.keepAlive) {
this.dialogVisible = false
}
this.$emit(`handleConfirm${btn.type}`, data, btn)
if (!btn.notReset) {
this.$refs.form.resetFields()
}
}
} else {
console.log('error submit!!')
return false
}
})
},
handleCheckKeys(data) {
var ids = this.$refs['startTree' + data.prop][0].getCheckedKeys()
this.form[data.prop] = ids
},
handleCheckChange(data, node) {
this.$emit(`getTheNod`, node.checkedKeys, data, node)
this.$emit(`getTheNod${data.prop}`, node.checkedKeys, data, node)
this.form[data.prop] = node.checkedKeys
},
// 隐藏表单
hiddenFn(item, form) {
var status = true
if (item.hiddenKey) {
status = form[item.hiddenKey] === item.hiddenValue
} else if (item.hiddenKeys && item.hiddenKeys instanceof Array) {
item.hiddenKeys.forEach((v, i) => {
if (form[v] !== item.hiddenValues[i]) {
status = false
}
})
} else if (item.hidden instanceof Function) {
status = item.hidden(form)
} else if (item.hiddenFunc instanceof Function) {
status = item.hiddenFunc(form)
}
return status
},
getOptions(item) {
const { options } = item || {}
if (options instanceof Array) {
return options
} else if (options instanceof String && this[options] instanceof Array) {
return this[options]
} else {
return []
}
},
getCascaderProps(item) {
return { checkStrictly: true, ...(item.props || {}) }
},
handleChangeCascader(item, val) {
this.$refs.cascader[0].dropDownVisible = false
this.$emit('handleChangeCascader', item, val)
},
change(item) {
this.$emit('handleSelectChange', item)
}
}
}
</script>
<style lang="scss">
.el-transfer-panel {
width: 335px !important;
}
.form-dialog-container {
.el-input,
.el-textarea,
.el-cascader,
.el-select {
max-width: 300px;
width: 100%;
}
.el-form-item {
margin-bottom: 16px !important;
}
.foot-text {
color: #666666;
font-size: 14px;
margin-right: 20px;
}
.el-dialog {
.el-dialog__body {
.el-form {
.form-item-wrap {
/*
&:not(:first-of-type):last-of-type .el-form-item{
margin-bottom: 0;
}
*/
&:last-of-type .el-form-item {
margin-bottom: 0;
}
}
}
}
}
.el-tree {
.el-tree-node .el-tree-node__content .el-checkbox {
margin-right: 8px;
.el-checkbox__inner {
border-radius: 0px !important;
}
}
}
.el-switch {
height: 16px;
margin-top: -2px;
}
.switch-text {
margin-left: 10px;
font-size: 12px;
}
.el-textarea {
min-height: 32px;
height: inherit !important;
.el-textarea__inner {
min-height: 32px !important;
height: inherit;
line-height: 28px;
}
}
.check-share {
padding: 5px 10px;
color: #666;
font-size: 14px;
.check-share-label {
margin-bottom: 10px;
padding-left: 20px;
.jee-svg-icon {
fill: #666;
position: relative;
top: 0.5px;
margin-right: 5px;
}
}
.check-share-title {
color: #333;
font-size: 16px;
line-height: 1;
margin-right: 70px;
position: relative;
top: 2px;
}
.el-checkbox-group {
min-height: 32px;
height: inherit;
padding: 10px 20px 0;
box-sizing: border-box;
border: 1px dashed #E8E8E8;
.el-checkbox {
min-width: 65.3px;
.el-checkbox__inner {
border-radius: 100%;
line-height: 1.3;
}
.el-checkbox__label {
line-height: 1.3;
}
}
}
}
.tag-wrap {
// padding: 0 30px;
.tree-box-label {
line-height: 1;
margin-bottom: 20px;
display: block;
}
.tree-box {
width: 100%;
max-width: 300px; // 可以注释掉,单独配置宽度
max-height: 330px;
min-height: 100px;
overflow: overlay;
padding-top: 10px;
box-sizing: border-box;
border: 1px solid #e8e8e8;
.el-tree {
background-color: #fff;
margin-left: 1px;
}
.right-radio {
display: inline-block;
position: absolute;
right: 30px;
.el-radio__label {
display: none;
}
.el-checkbox__inner {
border-radius: 100%;
}
}
}
.label-box {
min-height: 31px;
width: 100%;
box-sizing: border-box;
border: 1px dashed #E8E8E8;
margin-bottom: 20px;
padding: 9px 0 0 20px;
.tag-item {
height: 22px;
line-height: 20px;
margin-bottom: 9px;
margin-right: 20px;
font-size: 12px;
.el-tag__close {
color: #999;
&:hover {
background-color: transparent;
}
}
}
}
}
.el-alert {
height: 42px;
box-sizing: border-box;
.el-alert__title {
font-size: 12px;
}
}
.careful-txt {
color: #666666;
padding: 0 15px;
font-size: 14px;
font-weight: 400;
line-height: 28px;
margin-bottom: 30px;
.careful-label {
color: #FF0000;
}
}
.el-upload-list .el-upload-list__item {
// position: absolute;
line-height: 31px;
// top: 64px;
width: 300px;
box-sizing: border-box;
border: 1px solid #E8E8E8;
margin-bottom: 10px;
padding: 0 15px;
.el-icon-close {
top: 10px;
}
}
.check-tree-wrap {
overflow: overlay;
width: 300px;
height: 180px;
border: 1px solid #e8e8e8;
border-radius: 4px;
padding: 10px 0;
.el-tree-node__content {
height: 32px;
}
.el-checkbox__input {
vertical-align: text-bottom;
}
}
}
</style>
效果展示
该模块代码展示
index.vue
<template>
<div class="tab-container">
<base-header
v-bind="headers"
@handleCreate="handleHeaderCreate"
@handleStart="handleHeaderStart"
@handleStop="handleHeaderStop"
@handleDelete="handleHeaderDelete"
/>
<search-header
class="search-header"
v-bind="searchHeader"
:params="list.params"
@handleBtnSearch="handleSearch"
@handleSearch="handleSearch"
/>
<base-table
v-bind="list"
@handleEdit="handleTableEdit"
@handleDetail="handleTableDetail"
@handleStatus="handleTableStatus"
@handleSelectionChange="handleSelectionChange"
@handleSizeChange="handleSizeChange"
@handleCurrentChange="handleCurrentChange"
@handleDelete="handleTableDelete"
/>
<form-dialog
ref="addDialog"
:loading="formLoading"
title="新建"
:form="addForm"
:rules="addRules"
:form-items="addFormItems"
:buttons="[{text: '保存继续新增',type: 'Submit',keepAlive: true},{text: '保存',type: 'Submit'}]"
@opened="handleAddFormOpened"
@handleConfirm="handleConfirmAdd"
@handleSelectChange="handleAddFormChange"
/>
<form-dialog
ref="editDialog"
:loading="formLoading"
:form="editForm"
:rules="editRules"
title="修改"
:form-items="editFormItems"
@opened="handleEditFormOpened"
@handleConfirm="handleConfirmEdit"
/>
<form-dialog
ref="detailDialog"
:loading="formLoading"
:form="detailForm"
title="详情"
:show-cancel="false"
:buttons="[]"
:form-items="detailFormItems"
@opened="handleDetailFormOpened"
/>
</div>
</template>
<script>
import baseHeader from '@/components/myComponents/mixins/baseHeader'
import baseTable from '@/components/myComponents/mixins/baseTable'
import searchHeader from '@/components/myComponents/mixins/searchHeader'
import formDialog from '@/components/myComponents/mixins/formDialog'
import base from '@/views/appManage/appList/dialog/base'
import addFormDialog from '@/views/appManage/appList/dialog/addFormDialog'
import editFormDialog from '@/views/appManage/appList/dialog/editFormDialog'
import detailFormDialog from '@/views/appManage/appList/dialog/detailFormDialog'
export default {
name: 'AlarmStrategy',
mixins: [baseTable, searchHeader, baseHeader, formDialog],
data() {
return {
formLoading: false,
headers: base.headers,
searchHeader: base.searchHeader,
list: base.list,
addForm: addFormDialog.form,
addRules: addFormDialog.rules,
addFormItems: addFormDialog.formItems,
editForm: editFormDialog.form,
editRules: editFormDialog.rules,
editFormItems: editFormDialog.formItems,
detailForm: detailFormDialog.form,
detailFormItems: detailFormDialog.formItems
}
},
watch: {},
created() {
},
mounted() {
},
methods: {
// 修改-点击
handleTableStatus(row, index, item) {
editFormDialog.handle.handleTableStatus(this, row, index, item)
},
// 修改-点击
handleTableEdit(row, index, item) {
editFormDialog.handle.table(this, row, index, item)
},
// 修改-打开对话框回调
handleEditFormOpened() {
editFormDialog.handle.handleEditFormOpened(this)
},
// 修改-保存
handleConfirmEdit(data) {
editFormDialog.handle.confirm(this, data)
},
// 新建-点击
handleHeaderCreate() {
addFormDialog.handle.create(this)
},
// 新建-打开对话框
handleAddFormOpened() {
addFormDialog.handle.handleAddFormOpened(this)
},
// 新建-保存
handleConfirmAdd(data) {
addFormDialog.handle.confirm(this, data)
},
// 新建-对话框-下拉框-change事件回调
handleAddFormChange(item) {
addFormDialog.handle.handleAddFormChange(this, item)
},
// 详情
handleTableDetail(row, index, item) {
detailFormDialog.handle.table(this, row, index, item)
},
// 详情打开后回调
handleDetailFormOpened() {
detailFormDialog.handle.handleDetailFormOpened()
},
handleSelectionChange() {
},
handleTableDelete(row, index, item) {
base.handle.handleTableDelete(this, row, index, item)
},
handleMemberStatus() {
},
handleHeaderStart() {
},
handleHeaderStop() {
},
handleHeaderDelete() {
},
handleSearch() {
this.list.pageNo = 1
this.fetchTableApi()
},
fetchTableCallBack(res) {
base.handle.fetchTableCallBack(this, res)
}
}
}
</script>
<style scoped>
</style>
base.js
const columns = [
{
prop: 'name',
label: '名称',
minWidth: '80px'
},
{
prop: 'appKey',
label: 'appKey',
minWidth: '100px'
},
{
prop: 'appSecret',
label: 'appSecret',
minWidth: '100px'
},
{
scopeType: 'switch',
prop: 'status',
type: 'Status',
label: '状态',
minWidth: '40px'
},
{
// scopeType: 'time',
prop: 'createDateTime',
label: '创建日期时间',
minWidth: '50px'
}
]
const headers = {
buttons: [
{
type: 'Create',
text: '新建',
icon: 'xinjian'
}
],
title: '',
showAlertIcon: false,
content: '操作说明'
}
const searchHeader = {
searchItems: [
{
type: 'input',
value: 'name',
label: '名称:',
clearable: true
},
{
type: 'searchInput',
value: 'appKey',
label: 'appKey:',
clearable: true
}
]
}
const list = {
columns,
api: 'queryAppPage',
pageSizes: [1, 5, 10],
params: {
name: '',
appKey: ''
},
handleColumn: [
{
type: 'Edit',
name: '修改',
icon: 'delete'
},
{
type: 'Delete',
name: '删除',
icon: 'delete'
},
{
type: 'Detail',
name: '查看详情',
icon: 'delete'
}
],
handleColumnProp: {
width: '75px'
}
}
const handle = {
fetchTableCallBack(this_, res) {
console.log('fetchTableCallBack', res)
debugger
if (res.code === 200) {
this_.list.data = res.data.list.map(d => {
d.createDateTime = this_.$dateUtil.formateDate(new Date(d.createDateTime))
return d
})
this_.list.totalCount = res.data.total
}
},
handleTableDelete(this_, row, index, item) {
this_.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this_.$request.deleteApp(row.id).then(this_.hideTableLoading)
.then(this_.fetchTableApi(true))
.catch(this_.hideTableLoading)
}).catch(() => {
this_.$message({
type: 'info',
message: '已取消删除'
})
})
}
}
export default {
columns,
headers,
searchHeader,
list,
handle
}
addFormDialog.js
import rules_ from '@/utils/rules.js'
const form = {
name: '',
notice: '',
appKey: '',
appSecret: '',
status: true
}
const rules = {
englishName: [rules_.required(), rules_.enNumLine(), rules_.min(4), rules_.max(18)],
chineseName: [rules_.required(), rules_.cnEnNumPath(), rules_.min(4), rules_.max(18)],
password: [rules_.required(), rules_.password1()],
authoriseCode: [rules_.required(), rules_.password1()],
benefitPercent: [rules_.required(), rules_.plusNumber()]
}
const formItems = [
{
prop: 'name',
label: '名称'
},
{
prop: 'notice',
label: '公告'
},
{
prop: 'appKey',
label: 'appKey'
},
{
prop: 'appSecret',
label: 'appSecret'
},
{
type: 'switch',
prop: 'status',
label: '状态'
}
]
const handle = {
confirm(this_, data) {
console.log('handleConfirmAdd')
console.log(data)
this_.$request.addApp(data)
.then(this_.hideTableLoading)
.then(this_.fetchTableApi(true))
.catch(this_.hideTableLoading)
},
create(this_) {
console.log('handleHeaderCreate')
this_.$refs.addDialog.showDialog()
},
handleAddFormOpened(this_) {
},
handleAddFormChange(this_, item) {
console.log(item)
if (item.prop === 'alarmType') {
this_.addForm.template = item.template[this_.addForm.alarmType]
}
}
}
export default {
form,
rules,
formItems,
handle
}