build v3.7.2

This commit is contained in:
smallwei
2025-08-26 09:15:51 +08:00
parent 7bda781331
commit 2438209302
9 changed files with 304 additions and 268 deletions

File diff suppressed because one or more lines are too long

4
lib/avue.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"name": "@smallwei/avue",
"version": "3.7.1",
"version": "3.7.2",
"description": "A Magic Configurable Web Framework",
"main": "lib/avue.min.js",
"unpkg": "lib/avue.min.js",

View File

@@ -1,29 +1,31 @@
<template>
<el-cascader ref="cascader"
:options="dic"
:class="b()"
@click="handleClick"
@change="handleValueChange"
v-model="text"
:placeholder="placeholder"
:props="allProps"
:size="size"
:clearable="clearableVal"
:show-all-levels="showAllLevels"
:filterable="filterable"
:popper-class="popperClass"
:separator="separator"
:disabled="disabled"
:collapse-tags="tags || collapseTags"
:collapse-tags-tooltip="collapseTagsTooltip"
:max-collapse-tags="maxCollapseTags"
@focus="handleFocus"
@blur="handleBlur">
<template #="{data,node}">
<slot v-if="$slots.default"
:data="data"
:node="node"></slot>
<span v-else>{{data[labelKey]}}</span>
<el-cascader
ref="cascader"
:options="dic"
:class="b()"
@click="handleClick"
@change="handleValueChange"
v-model="text"
:placeholder="placeholder"
:props="allProps"
:size="size"
:effect="effect"
:clearable="clearableVal"
:show-all-levels="showAllLevels"
:filterable="filterable"
:popper-class="popperClass"
:separator="separator"
:disabled="disabled"
:show-checked-strategy="showCheckedStrategy"
:collapse-tags="tags || collapseTags"
:collapse-tags-tooltip="collapseTagsTooltip"
:max-collapse-tags="maxCollapseTags"
@focus="handleFocus"
@blur="handleBlur"
>
<template #="{ data, node }">
<slot v-if="$slots.default" :data="data" :node="node"></slot>
<span v-else>{{ data[labelKey] }}</span>
</template>
</el-cascader>
</template>
@@ -37,44 +39,46 @@ export default create({
mixins: [props(), event()],
props: {
clearValidate: Function,
effect: String,
showCheckedStrategy: String,
checkStrictly: {
type: Boolean,
default: false
default: false,
},
emitPath: {
type: Boolean,
default: true
default: true,
},
tags: {
type: Boolean,
default: false
default: false,
},
collapseTags: Boolean,
collapseTagsTooltip: Boolean,
maxCollapseTags: Number,
expandTrigger: {
type: String,
default: "hover"
default: "hover",
},
showAllLevels: {
type: Boolean,
default: true
default: true,
},
lazy: {
type: Boolean,
default: false
default: false,
},
lazyLoad: Function,
filterable: {
type: Boolean,
default: false
default: false,
},
separator: {
type: String
}
type: String,
},
},
computed: {
allProps () {
allProps() {
return {
label: this.labelKey,
value: this.valueKey,
@@ -90,36 +94,36 @@ export default create({
lazyLoad: (node, resolve) => {
let callback = (list) => {
let findDic = (list, value, children) => {
list.forEach(ele => {
list.forEach((ele) => {
if (ele[this.valueKey] == value) {
ele[this.childrenKey] = children
ele[this.childrenKey] = children;
} else if (ele[this.childrenKey]) {
findDic(ele[this.childrenKey])
findDic(ele[this.childrenKey]);
}
})
}
findDic(this.dic, node[this.valueKey], list)
});
};
findDic(this.dic, node[this.valueKey], list);
resolve(list);
}
this.lazyLoad && this.lazyLoad(node, callback)
};
this.lazyLoad && this.lazyLoad(node, callback);
},
expandTrigger: this.expandTrigger
}
}
expandTrigger: this.expandTrigger,
};
},
},
created () { },
mounted () { },
created() {},
mounted() {},
methods: {
handleValueChange (val) {
handleValueChange(val) {
setTimeout(() => {
if (!this.validatenull(val) && this.rules && this.clearValidate) {
this.clearValidate(this.prop)
this.clearValidate(this.prop);
}
})
});
},
getCheckedNodes (leafOnly = false) {
return this.$refs.cascader.getCheckedNodes(leafOnly)
}
}
getCheckedNodes(leafOnly = false) {
return this.$refs.cascader.getCheckedNodes(leafOnly);
},
},
});
</script>

View File

@@ -1,76 +1,98 @@
<template>
<component v-if="boxVisible"
:is="dialogType"
:draggable="validData(crud.tableOption.dialogDrag,config.dialogDrag)"
:class="['avue-dialog',b('dialog'),this.crud.tableOption.dialogCustomClass]"
:append-to-body="validData(crud.tableOption.dialogAppendToBody,true)"
:top="dialogTop"
:title="dialogTitle"
:close-on-press-escape="crud.tableOption.dialogEscape"
:close-on-click-modal="validData(crud.tableOption.dialogClickModal,false)"
:modal="crud.tableOption.dialogModal"
:show-close="crud.tableOption.dialogCloseBtn"
v-model="boxVisible"
v-bind="params"
:before-close="hide">
<component
v-if="boxVisible"
:is="dialogType"
:draggable="validData(crud.tableOption.dialogDrag, config.dialogDrag)"
:class="[
'avue-dialog',
b('dialog'),
this.crud.tableOption.dialogCustomClass,
]"
:append-to-body="validData(crud.tableOption.dialogAppendToBody, true)"
:top="dialogTop"
:title="dialogTitle"
:close-on-press-escape="crud.tableOption.dialogEscape"
:close-on-click-modal="validData(crud.tableOption.dialogClickModal, false)"
:modal="crud.tableOption.dialogModal"
:modal-penetrable="crud.tableOption.modalPenetrable"
:show-close="crud.tableOption.dialogCloseBtn"
:header-class="crud.tableOption.headerClass"
:body-class="crud.tableOption.bodyClass"
:footer-class="crud.tableOption.footerClass"
v-model="boxVisible"
v-bind="params"
:before-close="hide"
>
<template #header>
<div :class="b('dialog__header')">
<span class="el-dialog__title">{{dialogTitle}}</span>
<span class="el-dialog__title">{{ dialogTitle }}</span>
<div :class="b('dialog__menu')">
<el-icon class='el-dialog__close'
@click="handleFullScreen">
<component :is="fullscreen?'el-icon-copy-document':'el-icon-full-screen'" />
<el-icon class="el-dialog__close" @click="handleFullScreen">
<component
:is="fullscreen ? 'el-icon-copy-document' : 'el-icon-full-screen'"
/>
</el-icon>
</div>
</div>
</template>
<avue-form v-model="crud.tableForm"
v-model:status="disabled"
ref="tableForm"
@change="handleChange"
@submit="handleSubmit"
@reset-change="hide"
@tab-click="handleTabClick"
@error="handleError"
v-bind="$uploadFun(null,crud)"
v-loading="loading"
:element-loading-text="crud.tableOption.loadingText"
:element-loading-spinner="crud.tableOption.loadingSpinner"
:element-loading-svg="crud.tableOption.loadingSvg"
:element-loading-background="crud.tableOption.loadingBackground"
:option="option">
<avue-form
v-model="crud.tableForm"
v-model:status="disabled"
ref="tableForm"
@change="handleChange"
@submit="handleSubmit"
@reset-change="hide"
@tab-click="handleTabClick"
@error="handleError"
v-bind="$uploadFun(null, crud)"
v-loading="loading"
:element-loading-text="crud.tableOption.loadingText"
:element-loading-spinner="crud.tableOption.loadingSpinner"
:element-loading-svg="crud.tableOption.loadingSvg"
:element-loading-background="crud.tableOption.loadingBackground"
:option="option"
>
<!-- 循环form表单卡槽 -->
<template v-for="item in crud.formSlot"
#[getSlotName(item)]="scope">
<slot :name="item"
v-bind="Object.assign(scope,{type:boxType})"></slot>
<template v-for="item in crud.formSlot" #[getSlotName(item)]="scope">
<slot
:name="item"
v-bind="Object.assign(scope, { type: boxType })"
></slot>
</template>
</avue-form>
<span class="avue-dialog__footer"
:class="'avue-dialog__footer--'+dialogMenuPosition">
<slot name="menu-form-before"
v-bind="menuParams()"></slot>
<el-button type="primary"
@click="($refs.tableForm || {}).handleMock"
:loading="disabled||loading"
:size="crud.size"
:icon="option.mockIcon"
v-if="validData(option.mockBtn,false) && !isView">
{{option.mockText}}
<span
class="avue-dialog__footer"
:class="'avue-dialog__footer--' + dialogMenuPosition"
>
<slot name="menu-form-before" v-bind="menuParams()"></slot>
<el-button
type="primary"
@click="($refs.tableForm || {}).handleMock"
:loading="disabled || loading"
:size="crud.size"
:icon="option.mockIcon"
v-if="validData(option.mockBtn, false) && !isView"
>
{{ option.mockText }}
</el-button>
<el-button v-if="validData(option.submitBtn,true) && !isView"
@click="submit"
:loading="disabled||loading"
:size="crud.size"
:icon="option.submitIcon"
type="primary">{{option.submitText}}</el-button>
<el-button v-if="validData(option.emptyBtn,true) && !isView"
@click="reset"
:disabled="disabled||loading"
:size="crud.size"
:icon="option.emptyIcon">{{option.emptyText}}</el-button>
<slot name="menu-form"
v-bind="menuParams()"></slot>
<el-button
v-if="validData(option.submitBtn, true) && !isView"
@click="submit"
:loading="disabled || loading"
:size="crud.size"
:icon="option.submitIcon"
type="primary"
>{{ option.submitText }}</el-button
>
<el-button
v-if="validData(option.emptyBtn, true) && !isView"
@click="reset"
:disabled="disabled || loading"
:size="crud.size"
:icon="option.emptyIcon"
>{{ option.emptyText }}</el-button
>
<slot name="menu-form" v-bind="menuParams()"></slot>
</span>
</component>
</template>
@@ -79,20 +101,20 @@
import create from "core/create";
import locale from "core/locale";
import config from "../config";
import { filterParams } from 'utils/util'
import { filterParams } from "utils/util";
export default create({
name: "crud",
mixins: [locale],
emits: ['update:modelValue', 'change'],
emits: ["update:modelValue", "change"],
inject: ["crud"],
data () {
data() {
return {
loading: false,
disabled: false,
config: config,
boxType: "",
fullscreen: false,
boxVisible: false
boxVisible: false,
};
},
props: {
@@ -100,193 +122,200 @@ export default create({
type: Object,
default: () => {
return {};
}
}
},
},
},
computed: {
isView () {
return this.boxType === 'view'
isView() {
return this.boxType === "view";
},
isAdd () {
return this.boxType === 'add'
isAdd() {
return this.boxType === "add";
},
isEdit () {
return this.boxType === 'edit'
isEdit() {
return this.boxType === "edit";
},
width () {
let dialogWidth = this.crud.tableOption.dialogWidth + ''
let defaultWidth = this.crud.isMobile ? '100%' : config.dialogWidth;
width() {
let dialogWidth = this.crud.tableOption.dialogWidth + "";
let defaultWidth = this.crud.isMobile ? "100%" : config.dialogWidth;
let result = this.validData(dialogWidth, defaultWidth);
return this.setPx(result)
return this.setPx(result);
},
dialogType () {
return this.isDrawer ? 'elDrawer' : 'elDialog'
dialogType() {
return this.isDrawer ? "elDrawer" : "elDialog";
},
dialogTop () {
return (!this.isDrawer && !this.fullscreen) ? this.crud.tableOption.dialogTop : '0'
dialogTop() {
return !this.isDrawer && !this.fullscreen
? this.crud.tableOption.dialogTop
: "0";
},
isDrawer () {
return this.crud.tableOption.dialogType === 'drawer';
isDrawer() {
return this.crud.tableOption.dialogType === "drawer";
},
params () {
let result = this.isDrawer ?
{
size: this.fullscreen ? '100%' : this.width,
direction: this.crud.tableOption.dialogDirection
} : {
width: this.width,
fullscreen: this.fullscreen
};
return Object.assign(result, this.$uploadFun({}, this.crud))
params() {
let result = this.isDrawer
? {
size: this.fullscreen ? "100%" : this.width,
direction: this.crud.tableOption.dialogDirection,
}
: {
width: this.width,
fullscreen: this.fullscreen,
};
return Object.assign(result, this.$uploadFun({}, this.crud));
},
option () {
option() {
let option = this.deepClone(this.crud.tableOption);
option.boxType = this.boxType;
option.column = this.deepClone(this.crud.propOption);
option.column.forEach(ele => {
delete ele.render
if (ele.renderForm) ele.render = ele.renderForm
})
option.column.forEach((ele) => {
delete ele.render;
if (ele.renderForm) ele.render = ele.renderForm;
});
option.menuBtn = false;
if (this.isAdd) {
option.submitBtn = option.saveBtn;
option.submitText = this.crud.menuIcon('saveBtn');
option.submitIcon = this.crud.getBtnIcon('saveBtn')
option.submitText = this.crud.menuIcon("saveBtn");
option.submitIcon = this.crud.getBtnIcon("saveBtn");
} else if (this.isEdit) {
option.submitBtn = option.updateBtn;
option.submitText = this.crud.menuIcon('updateBtn');
option.submitIcon = this.crud.getBtnIcon('updateBtn')
option.submitText = this.crud.menuIcon("updateBtn");
option.submitIcon = this.crud.getBtnIcon("updateBtn");
} else if (this.isView) {
option.detail = true;
}
option.mockIcon = this.crud.getBtnIcon('mockBtn')
option.mockText = this.crud.menuIcon('mockBtn')
option.mockIcon = this.crud.getBtnIcon("mockBtn");
option.mockText = this.crud.menuIcon("mockBtn");
option.emptyBtn = option.cancelBtn;
option.emptyIcon = this.crud.getBtnIcon('cancelBtn')
option.emptyText = this.crud.menuIcon('cancelBtn')
option.emptyIcon = this.crud.getBtnIcon("cancelBtn");
option.emptyText = this.crud.menuIcon("cancelBtn");
//不分组的表单不加载字典
if (!this.crud.isGroup) {
option.dicFlag = false;
option.dicData = this.crud.DIC;
}
if (!this.validatenull(option.dicFlag)) {
option.column.forEach(ele => {
option.column.forEach((ele) => {
ele.boxType = this.boxType;
ele.dicFlag = ele.dicFlag || option.dicFlag
})
ele.dicFlag = ele.dicFlag || option.dicFlag;
});
}
return option;
},
dialogTitle () {
dialogTitle() {
const key = `${this.boxType}`;
if (!this.validatenull(this.boxType)) {
return this.crud.tableOption[key + 'Title'] || this.t(`crud.${key}Title`);
return (
this.crud.tableOption[key + "Title"] || this.t(`crud.${key}Title`)
);
}
},
dialogMenuPosition () {
return this.crud.tableOption.dialogMenuPosition || 'right'
}
dialogMenuPosition() {
return this.crud.tableOption.dialogMenuPosition || "right";
},
},
methods: {
menuParams () {
menuParams() {
return {
disabled: this.disabled,
size: this.crud.size,
type: this.boxType
}
type: this.boxType,
};
},
submit () {
this.$refs.tableForm.submit()
submit() {
this.$refs.tableForm.submit();
},
reset () {
this.$refs.tableForm.resetForm(false)
reset() {
this.$refs.tableForm.resetForm(false);
},
getSlotName (item) {
return item.replace('-form', '')
getSlotName(item) {
return item.replace("-form", "");
},
handleChange () {
this.crud.setVal()
handleChange() {
this.crud.setVal();
},
handleTabClick (tab, event) {
this.crud.$emit('tab-click', tab, event)
handleTabClick(tab, event) {
this.crud.$emit("tab-click", tab, event);
},
handleFullScreen () {
handleFullScreen() {
if (this.fullscreen) {
this.fullscreen = false;
} else {
this.fullscreen = true;
}
},
handleError (error) {
this.crud.$emit('error', error)
handleError(error) {
this.crud.$emit("error", error);
},
handleSubmit (form, hide) {
handleSubmit(form, hide) {
if (this.isAdd) {
this.rowSave(hide);
} else if (this.isEdit) {
this.rowUpdate(hide);
}
},
initFun () {
['clearValidate', 'validate', 'resetForm', 'validateField'].forEach(ele => {
this.crud[ele] = this.$refs.tableForm[ele]
})
initFun() {
["clearValidate", "validate", "resetForm", "validateField"].forEach(
(ele) => {
this.crud[ele] = this.$refs.tableForm[ele];
}
);
},
// 保存
rowSave (hide) {
rowSave(hide) {
this.crud.$emit(
"row-save",
filterParams(this.crud.tableForm, ['$']),
filterParams(this.crud.tableForm, ["$"]),
this.closeDialog,
hide
);
},
// 更新
rowUpdate (hide) {
rowUpdate(hide) {
this.crud.$emit(
"row-update",
filterParams(this.crud.tableForm, ['$']),
filterParams(this.crud.tableForm, ["$"]),
this.crud.tableIndex,
this.closeDialog,
hide
);
},
closeDialog (row, index) {
closeDialog(row, index) {
row = this.deepClone(row);
const callback = () => {
if (this.isEdit) {
let { parentList, index } = this.crud.findData(row[this.crud.rowKey])
let { parentList, index } = this.crud.findData(row[this.crud.rowKey]);
if (parentList) {
const oldRow = parentList.splice(index, 1)[0];
row[this.crud.childrenKey] = oldRow[this.crud.childrenKey]
parentList.splice(index, 0, row)
row[this.crud.childrenKey] = oldRow[this.crud.childrenKey];
parentList.splice(index, 0, row);
}
} else if (this.isAdd) {
let { item } = this.crud.findData(row[this.crud.rowParentKey])
let { item } = this.crud.findData(row[this.crud.rowParentKey]);
if (item) {
if (!item[this.crud.childrenKey]) {
item[this.crud.childrenKey] = []
item[this.crud.childrenKey] = [];
}
if (this.crud.tableOption.lazy) {
item[this.crud.hasChildrenKey] = true
item[this.crud.hasChildrenKey] = true;
}
item[this.crud.childrenKey].push(row)
item[this.crud.childrenKey].push(row);
} else {
this.crud.list.push(row);
}
}
}
};
if (row) callback();
this.hide();
},
// 隐藏表单
hide (done) {
hide(done) {
const callback = () => {
done && done();
this.crud.tableIndex = -1;
this.crud.tableForm = {}
this.crud.setVal()
this.crud.tableForm = {};
this.crud.setVal();
this.boxVisible = false;
};
if (typeof this.crud.beforeClose === "function") {
@@ -296,29 +325,28 @@ export default create({
}
},
// 显示表单
show (type) {
show(type) {
this.boxType = type;
const callback = (fn) => {
this.fullscreen = this.crud.tableOption.dialogFullscreen
this.fullscreen = this.crud.tableOption.dialogFullscreen;
this.boxVisible = true;
this.loading = false
this.loading = false;
this.$nextTick(() => {
this.initFun()
fn && fn()
})
this.initFun();
fn && fn();
});
};
const loading = () => {
callback(() => {
this.loading = true
this.loading = true;
});
}
};
if (typeof this.crud.beforeOpen === "function") {
this.crud.beforeOpen(callback, this.boxType, loading);
} else {
callback();
}
}
}
},
},
});
</script>

View File

@@ -1,28 +1,30 @@
<template>
<el-input-number v-model="text"
:class="b()"
@click="handleClick"
@focus="handleFocus"
@blur="handleBlur"
:precision="precision"
:placeholder="placeholder"
:step-strictly="stepStrictly"
:size="size"
:min="min"
:max="max"
:step="step"
:clearable="clearableVal"
:readonly="readonly"
:controls-position="controlsPosition"
:controls="controls"
:disabled="disabled">
<template #prefix
v-if="prefix">
<span @click="prefixClick(text)">{{prefix}}</span>
<el-input-number
v-model="text"
:class="b()"
@click="handleClick"
@focus="handleFocus"
@blur="handleBlur"
:precision="precision"
:placeholder="placeholder"
:step-strictly="stepStrictly"
:size="size"
:min="min"
:align="align"
:max="max"
:step="step"
:clearable="clearableVal"
:readonly="readonly"
:controls-position="controlsPosition"
:controls="controls"
:disabled-scientific="disabledScientific"
:disabled="disabled"
>
<template #prefix v-if="prefix">
<span @click="prefixClick(text)">{{ prefix }}</span>
</template>
<template #suffix
v-if="suffix">
<span @click="suffixClick(text)">{{suffix}}</span>
<template #suffix v-if="suffix">
<span @click="suffixClick(text)">{{ suffix }}</span>
</template>
</el-input-number>
</template>
@@ -34,54 +36,56 @@ import event from "common/common/event.js";
export default create({
name: "input-number",
mixins: [props(), event()],
data () {
data() {
return {};
},
props: {
align: String,
disabledScientific: Boolean,
stepStrictly: {
type: Boolean,
default: false
default: false,
},
controls: {
type: Boolean,
default: true
default: true,
},
step: {
type: Number,
default: 1
default: 1,
},
controlsPosition: {
type: String,
default: "right"
default: "right",
},
precision: {
type: Number
type: Number,
},
min: {
type: Number,
default: -Infinity
default: -Infinity,
},
max: {
type: Number,
default: Infinity
default: Infinity,
},
prefix: {
type: String,
},
prefixClick: {
type: Function,
default: () => { }
default: () => {},
},
suffix: {
type: String,
},
suffixClick: {
type: Function,
default: () => { }
default: () => {},
},
},
created () { },
mounted () { },
methods: {}
created() {},
mounted() {},
methods: {},
});
</script>

View File

@@ -1 +1 @@
export const version = '3.7.1'
export const version = '3.7.2'

View File

@@ -118,7 +118,7 @@ body {
color: #606266;
}
.el-select__wrapper.is-disabled .el-select__selected-item{
color:transparent;
color:#606266;
}
.el-form-item.is-required:not(.is-no-asterisk) .el-form-item__label-wrap>.el-form-item__label:before,