123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- <template>
- <div class="by-form" :style="{ width: attrs.width }">
- <el-descriptions v-if="attrs.showType == 'desc'" :title="attrs.title" :column="attrs.itemCount" :border="attrs.border"
- :direction="attrs.direction" :size="attrs.size ? attrs.size : 'medium'" :colon="attrs.colon"
- contentClassName="clas123">
- <template v-for="(itemChild, index) of columns">
- <el-descriptions-item :label="item.label" v-for="(item, _ind) of itemChild" :span="item.colspan"
- :key="index + '-' + _ind">
- <slot v-if="item.descSlot" :name='item.prop + "_desc"' :value='value'></slot>
- <template v-else>{{ value[item.prop] ? value[item.prop] : '--' }}</template>
- </el-descriptions-item>
- </template>
- </el-descriptions>
- <el-form class="byForm" v-else :style="{ height: attrs.height ? attrs.height + 'px' : 'auto' }" :model="value"
- ref="byForm" :validate-on-rule-change="false" :size="attrs.size ? attrs.size : 'small'" :inline-message="true"
- v-bind="$attrs" :disabled="attrs.disabled" :label-width="attrs.labelWidth ? attrs.labelWidth : '100px'"
- :rules="attrs.readonly ? {} : attrs.rules" :label-position="attrs.labelPosition ? attrs.labelPosition : ''">
- <el-row class="form-row" v-for="(itemChild, index) of columns" :key="index">
- <el-col v-for="(item, _ind) of itemChild" :span="item.span" :key="'itemChild' + _ind">
- <el-form-item class="by-form-item" :label="item.label" :rules="attrs.readonly ? [] : item.rules" :prop="item.prop"
- :required="item.required" :error="item.error" :size="item.size" :label-width="item.labelWidth">
- <component v-bind:is="item.component" class="form-comp" :propConfig="item.compConfig"
- :ref="item.prop + suffixCode" :parentValue="value" :propValue="value[item.prop]"
- @onChange="onChange($event, item)" v-bind="$attrs" v-on="$listeners" />
- <slot v-if="item.slot" :name='item.prop' :value='value'></slot>
- <!-- <slot :[item.prop]="value" ></slot> -->
- <div class="readonly-cover" v-if="attrs.readonly"></div>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <!-- <el-button @click="getValueData">获取数据</el-button> -->
- </div>
- </template>
- <script lang="ts">
- /*
- 基础配置
- config:{
- attr:{
- width:'', //表单宽度
- showType: '' //展示形式
- title:'' //标题(desc的时候用)
- itemCount:'' //每行展示几列(desc的时候用)
- border:true/false //是否有边框(desc的时候用)
- direction: vertical / horizontal 排列的方向(desc的时候用)
- colon:true/false //是否显示冒号 (desc的时候用)
- disabled:true/false //表单禁用
- readonly:true/false //表单只读
- size:medium / small / mini, //表单域下组件的尺寸,
- height:'', //高度
- labelPosition: right/left/top //标签位置
- labelWidth: '' //标签的宽度
- rules:[] //验证规则
- },
- columns: [[{ //表单列
- span:'' //分栏,
- label:'' //标签
- prop:'' //字段
- labelWidth:'' 标签的的宽度
- rule:{} //验证规则
- size:medium / small / mini //表单域下组件的尺寸,
- component:'' //组件
- compConfig:{} //组件配置
- slot:true/false //插槽
- colspan:'' //在itemCount的基础上 列的数量(desc的时候用)
- descSlot:true/false //插槽(desc的时候用)
- }]]
- request:{
- url:'',
- method:'',
- headers:{},
- data:{}
- }
- }
- */
- import { Component, Prop, Vue, Watch } from "vue-property-decorator";
- import VueViews from '@/benyun/compVue/VueViews'
- @Component
- export default class ByForm extends VueViews {
- value: any = {}
- suffixCode = "--comp"
- get columns() {
- let columns: Array<any> = this.config?.columns ? this.config.columns : []
- //分栏设置
- if (columns.length > 0) {
- for (const itemChild of columns) {
- let spans = 24
- let n = itemChild.length
- for (const item of itemChild) {
- if (item && ((Number(item.span) > 0 && Number(item.span) <= 24))) {
- spans = spans - Number(item.span)
- n--;
- }
- }
- for (const item of itemChild) {
- if (Number(item.span) > 0 && Number(item.span) <= 24) {
- item.span = Number(item.span)
- } else {
- item.span = spans / n
- }
- }
- }
- }
- return columns
- }
- created() {
- if (this.propConfig) {
- this.setConfig(this.propConfig)
- }
- }
- mounted() {
- if (this.attrs.data) {
- this.setValue(this.attrs.data);
- }
- }
- getValueData() {
- console.log('表单数据', this.value)
- }
- //设置数据
- setValue(data: any) {
- if (data) {
- this.value = (this as any).$lodash.cloneDeep(data);
- } else {
- this.value = {};
- }
- this.$nextTick(() => {
- this.setChildrenComValue();
- })
- setTimeout(() => {
- this.clearValidate();
- }, 100)
- this.$forceUpdate();
- }
- clearValue() {
- this.value = {};
- this.clearChildrenComp();
- this.defaultHandle();
- setTimeout(() => {
- this.clearValidate();
- }, 100)
- }
- //获取数据
- getValue() {
- return (this as any).$lodash.cloneDeep(this.value);
- }
- //设置表单内某组件配置
- setCompConfig(code: any, c: any) {
- if (this.$refs[code + this.suffixCode] && (this.$refs[code + this.suffixCode] as any)[0] && (this.$refs[code + this.suffixCode] as any)[0].setConfig) {
- (this.$refs[code + this.suffixCode] as any)[0].setConfig(c)
- }
- }
- setConfigAfter() {
- this.$nextTick(() => {
- if (this.columns.length > 0) {
- for (const itemData of this.columns) {
- for (const item of itemData) {
- if (this.$refs[item.prop + this.suffixCode] && (this.$refs[item.prop + this.suffixCode] as any)[0] && (this.$refs[item.prop + this.suffixCode] as any)[0].setConfig) {
- (this.$refs[item.prop + this.suffixCode] as any)[0].setConfig(item.compConfig)
- }
- }
- }
- }
- })
- }
- //清除下级组件组件值
- clearChildrenComp() {
- for (const key in this.$refs) {
- if (key.indexOf(this.suffixCode) >= 0 && (this as any).$refs[key][0] && (this as any).$refs[key][0].clearValue) {
- (this as any).$refs[key][0].clearValue()
- }
- }
- }
- //下级组件默认值
- defaultHandle() {
- for (const key in this.$refs) {
- if (key.indexOf(this.suffixCode) >= 0 && (this as any).$refs[key][0] && (this as any).$refs[key][0].defaultHandle) {
- (this as any).$refs[key][0].defaultHandle()
- }
- }
- }
- //设置下级组件值
- setChildrenComValue() {
- for (const key in (this as any).$refs) {
- if (key.indexOf(this.suffixCode) >= 0 && (this as any).$refs[key] && (this as any).$refs[key][0] && (this as any).$refs[key][0].setValue) {
- const code = key.split(this.suffixCode)[0];
- if (this.value) {
- (this as any).$refs[key][0].setValue(this.value[code])
- } else {
- (this as any).$refs[key][0].setValue(null)
- }
- }
- }
- }
- //表单数据变化
- onChange(v: any, config: any) {
- let code = config.prop;
- if (v && (v as any).constructor === Object) {
- for (const key in v) {
- this.changeSetValue(key, v[key])
- }
- } else {
- this.changeSetValue(code, v)
- }
- if ((this as any).$refs.byForm) {
- (this as any).$refs.byForm.validateField(code);
- }
- this.$emit('formChange', { value: v, code: code })
- }
- changeSetValue(code: string, v: any) {
- if (this.value[code]) {
- this.value[code] = v;
- } else {
- Vue.set(this.value, code, v);
- }
- }
- //表单验证
- validate(parames?: any): Promise<any> {
- return new Promise((resolve: Function, reject: Function) => {
- if (!this.$refs.byForm) {
- resolve(true)
- }
- const failHandel = () => {
- if (!parames || !parames.noMsg) {
- (this as any).$message({
- message: '验证未通过,请检查!',
- type: 'warning',
- })
- }
- reject()
- }
- (this as any).$refs.byForm.validate((valid: any) => {
- if (valid) {
- let va = true
- for (const col of this.columns) {
- for (const item of col) {
- if (this.$refs[item.prop + this.suffixCode] && (this.$refs[item.prop + this.suffixCode] as any)[0] && (this.$refs[item.prop + this.suffixCode] as any)[0].validate) {
- va = (this.$refs[item.prop + this.suffixCode] as any)[0].validate()
- if (!va) break
- }
- }
- if (!va) break
- }
- if (va) {
- resolve(true)
- } else {
- failHandel()
- }
- } else {
- failHandel()
- }
- });
- })
- }
- //清除过滤提示
- clearValidate() {
- if (this.$refs.byForm) {
- (this.$refs.byForm as any).clearValidate();
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .by-form {
- width: 100%;
- margin: 0 auto;
- .form-comp {
- width: 100%;
- }
- .readonly-cover {
- position: absolute;
- height: 100%;
- width: 100%;
- left: 0;
- top: 0;
- }
- }
- </style>
- <style lang="scss">
- .by-form-item {
- margin-bottom: 10px !important;
- }
- </style>
|