mirror of
https://github.com/cool-team-official/cool-admin-vue.git
synced 2025-12-13 06:02:49 +00:00
cl-form 添加 children 参数
This commit is contained in:
parent
02dad133a8
commit
520fd74d2b
5
.vscode/crud.code-snippets
vendored
5
.vscode/crud.code-snippets
vendored
@ -58,6 +58,11 @@
|
||||
" app.refresh();",
|
||||
" }",
|
||||
");",
|
||||
"",
|
||||
"// 刷新",
|
||||
"function refresh(params?: any) {",
|
||||
" Crud.value?.refresh(params);",
|
||||
"}",
|
||||
"</script>",
|
||||
""
|
||||
],
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "front-next",
|
||||
"version": "6.3.1",
|
||||
"version": "6.3.2",
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"build": "vite build",
|
||||
|
||||
13
packages/crud/index.d.ts
vendored
13
packages/crud/index.d.ts
vendored
@ -429,6 +429,18 @@ declare namespace ClForm {
|
||||
size?: "medium" | "default" | "small";
|
||||
[key: string]: any;
|
||||
};
|
||||
col?: {
|
||||
span: number;
|
||||
offset: number;
|
||||
push: number;
|
||||
pull: number;
|
||||
xs: any;
|
||||
sm: any;
|
||||
md: any;
|
||||
lg: any;
|
||||
xl: any;
|
||||
tag: string;
|
||||
};
|
||||
hook?: Hook.Form;
|
||||
group?: string;
|
||||
collapse?: boolean;
|
||||
@ -443,6 +455,7 @@ declare namespace ClForm {
|
||||
append?: Render.Component;
|
||||
rules?: Rule | Rule[];
|
||||
required?: boolean;
|
||||
children?: Item[];
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
||||
@ -138,7 +138,7 @@ export function useTabs({ config, Form }: { config: Config; Form: Form }) {
|
||||
}
|
||||
|
||||
// 切换
|
||||
function change(value: any, isValid: boolean = true) {
|
||||
function change(value: any, isValid = true) {
|
||||
return new Promise((resolve: Function, reject: Function) => {
|
||||
function next() {
|
||||
active.value = value;
|
||||
@ -146,7 +146,7 @@ export function useTabs({ config, Form }: { config: Config; Form: Form }) {
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
let isError: boolean = false;
|
||||
let isError = false;
|
||||
|
||||
const arr = config.items
|
||||
.filter((e: any) => e.group == active.value && !e._hidden && e.prop)
|
||||
|
||||
@ -274,35 +274,44 @@ export default defineComponent({
|
||||
|
||||
// 设置表单数据
|
||||
config.items.map((e) => {
|
||||
if (e.prop) {
|
||||
// 解析 prop
|
||||
if (e.prop.includes(".")) {
|
||||
e.prop = e.prop.replace(/\./g, "-");
|
||||
function deep(e: ClForm.Item) {
|
||||
if (e.prop) {
|
||||
// 解析 prop
|
||||
if (e.prop.includes(".")) {
|
||||
e.prop = e.prop.replace(/\./g, "-");
|
||||
}
|
||||
|
||||
// prop 合并
|
||||
Tabs.mergeProp(e);
|
||||
|
||||
// 绑定值
|
||||
formHook.bind({
|
||||
...e,
|
||||
value: form[e.prop] !== undefined ? form[e.prop] : cloneDeep(e.value),
|
||||
form
|
||||
});
|
||||
|
||||
// 表单验证
|
||||
if (e.required) {
|
||||
e.rules = {
|
||||
required: true,
|
||||
message: `${e.label}不能为空`
|
||||
};
|
||||
}
|
||||
|
||||
// 子集
|
||||
if (e.children) {
|
||||
e.children.forEach(deep);
|
||||
}
|
||||
}
|
||||
|
||||
// prop 合并
|
||||
Tabs.mergeProp(e);
|
||||
|
||||
// 绑定值
|
||||
formHook.bind({
|
||||
...e,
|
||||
value: form[e.prop] !== undefined ? form[e.prop] : cloneDeep(e.value),
|
||||
form
|
||||
});
|
||||
|
||||
// 表单验证
|
||||
if (e.required) {
|
||||
e.rules = {
|
||||
required: true,
|
||||
message: `${e.label}不能为空`
|
||||
};
|
||||
// 设置 tabs 默认值
|
||||
if (e.type == "tabs") {
|
||||
Tabs.set(e.value);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置 tabs 默认值
|
||||
if (e.type == "tabs") {
|
||||
Tabs.set(e.value);
|
||||
}
|
||||
deep(e);
|
||||
});
|
||||
|
||||
// 设置默认值
|
||||
@ -337,113 +346,131 @@ export default defineComponent({
|
||||
Object.assign(form, data);
|
||||
}
|
||||
|
||||
// 渲染表单及表单项
|
||||
function renderForm() {
|
||||
// 渲染表单项
|
||||
function renderFormItem(e: ClForm.Item) {
|
||||
const { isDisabled } = config._data;
|
||||
|
||||
// 表单项列表
|
||||
const children = config.items.map((e) => {
|
||||
if (e.type == "tabs") {
|
||||
return <cl-form-tabs v-model={Tabs.active.value} {...e.props} />;
|
||||
}
|
||||
if (e.type == "tabs") {
|
||||
return <cl-form-tabs v-model={Tabs.active.value} {...e.props} />;
|
||||
}
|
||||
|
||||
// 是否隐藏
|
||||
e._hidden = parseFormHidden(e.hidden, {
|
||||
scope: form
|
||||
});
|
||||
// 是否隐藏
|
||||
e._hidden = parseFormHidden(e.hidden, {
|
||||
scope: form
|
||||
});
|
||||
|
||||
// 分组显示
|
||||
const inGroup =
|
||||
isEmpty(Tabs.active.value) || isEmpty(e.group)
|
||||
? true
|
||||
: e.group === Tabs.active.value;
|
||||
// 分组显示
|
||||
const inGroup =
|
||||
isEmpty(Tabs.active.value) || isEmpty(e.group)
|
||||
? true
|
||||
: e.group === Tabs.active.value;
|
||||
|
||||
// 表单项
|
||||
const FormItem = e.component
|
||||
? h(
|
||||
<el-form-item
|
||||
class={{
|
||||
"no-label": !(e.renderLabel || e.label),
|
||||
"has-children": !!e.children
|
||||
}}
|
||||
label-width={props.inline ? "auto" : ""}
|
||||
label={e.label}
|
||||
prop={e.prop}
|
||||
rules={isDisabled ? null : e.rules}
|
||||
v-show={inGroup}
|
||||
/>,
|
||||
e.props,
|
||||
{
|
||||
label() {
|
||||
return e.renderLabel
|
||||
? renderNode(e.renderLabel, {
|
||||
scope: form,
|
||||
render: "slot",
|
||||
slots
|
||||
})
|
||||
: e.label;
|
||||
},
|
||||
default() {
|
||||
return (
|
||||
<div>
|
||||
<div class="cl-form-item">
|
||||
{["prepend", "component", "append"]
|
||||
.filter((k) => e[k])
|
||||
.map((name) => {
|
||||
const children = e.children && (
|
||||
<div class="cl-form-item__children">
|
||||
<el-row gutter={10}>
|
||||
{e.children.map(renderFormItem)}
|
||||
</el-row>
|
||||
</div>
|
||||
);
|
||||
|
||||
const Item = renderNode(e[name], {
|
||||
item: e,
|
||||
prop: e.prop,
|
||||
scope: form,
|
||||
slots,
|
||||
children,
|
||||
_data: {
|
||||
isDisabled
|
||||
}
|
||||
});
|
||||
|
||||
// 表单项
|
||||
const FormItem = e.component
|
||||
? h(
|
||||
<el-form-item
|
||||
label-width={props.inline ? "auto" : ""}
|
||||
label={e.label}
|
||||
prop={e.prop}
|
||||
rules={isDisabled ? null : e.rules}
|
||||
v-show={inGroup}
|
||||
/>,
|
||||
e.props,
|
||||
{
|
||||
label() {
|
||||
return e.renderLabel
|
||||
? renderNode(e.renderLabel, {
|
||||
scope: form,
|
||||
render: "slot",
|
||||
slots
|
||||
})
|
||||
: e.label;
|
||||
},
|
||||
default() {
|
||||
return (
|
||||
<div>
|
||||
<div class="cl-form-item">
|
||||
{["prepend", "component", "append"].map((name) => {
|
||||
return (
|
||||
e[name] && (
|
||||
<div
|
||||
v-show={!e.collapse}
|
||||
class={[
|
||||
`cl-form-item__${name}`,
|
||||
{
|
||||
flex1: e.flex !== false
|
||||
}
|
||||
]}
|
||||
style={e[name].style}>
|
||||
{renderNode(e[name], {
|
||||
item: e,
|
||||
prop: e.prop,
|
||||
scope: form,
|
||||
slots,
|
||||
_data: {
|
||||
isDisabled
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
<div
|
||||
v-show={!e.collapse}
|
||||
class={[
|
||||
`cl-form-item__${name}`,
|
||||
{
|
||||
flex1: e.flex !== false
|
||||
}
|
||||
]}
|
||||
style={e[name].style}>
|
||||
{Item}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{isBoolean(e.collapse) && (
|
||||
<div
|
||||
class="cl-form-item__collapse"
|
||||
onClick={() => {
|
||||
Action.collapseItem(e);
|
||||
}}>
|
||||
<el-divider content-position="center">
|
||||
{e.collapse ? "查看更多" : "隐藏内容"}
|
||||
</el-divider>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
{isBoolean(e.collapse) && (
|
||||
<div
|
||||
class="cl-form-item__collapse"
|
||||
onClick={() => {
|
||||
Action.collapseItem(e);
|
||||
}}>
|
||||
<el-divider content-position="center">
|
||||
{e.collapse ? "查看更多" : "隐藏内容"}
|
||||
</el-divider>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)
|
||||
: null;
|
||||
}
|
||||
)
|
||||
: null;
|
||||
|
||||
// 隐藏
|
||||
if (e._hidden) {
|
||||
return null;
|
||||
}
|
||||
// 隐藏
|
||||
if (e._hidden) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 行内
|
||||
if (props.inline) {
|
||||
return FormItem;
|
||||
}
|
||||
// 行内
|
||||
if (props.inline) {
|
||||
return FormItem;
|
||||
}
|
||||
|
||||
return (
|
||||
<el-col span={24} key={e.prop} {...e}>
|
||||
{FormItem}
|
||||
</el-col>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<el-col key={e.prop} span={e.span || 24} {...e.col}>
|
||||
{FormItem}
|
||||
</el-col>
|
||||
);
|
||||
}
|
||||
|
||||
// 渲染表单
|
||||
function renderForm() {
|
||||
// 表单项列表
|
||||
const children = config.items.map(renderFormItem);
|
||||
|
||||
return (
|
||||
<div class="cl-form__container">
|
||||
|
||||
@ -6,6 +6,7 @@ import AdvSearch from "./adv/search";
|
||||
import Flex from "./flex1";
|
||||
import Form from "./form";
|
||||
import FormTabs from "./form-tabs";
|
||||
import FormCard from "./form-card";
|
||||
import MultiDeleteBtn from "./multi-delete-btn";
|
||||
import Pagination from "./pagination";
|
||||
import Query from "./query";
|
||||
@ -27,6 +28,7 @@ export const components: { [key: string]: any } = {
|
||||
Flex,
|
||||
Form,
|
||||
FormTabs,
|
||||
FormCard,
|
||||
MultiDeleteBtn,
|
||||
Pagination,
|
||||
Query,
|
||||
|
||||
@ -6,8 +6,6 @@ import { mergeConfig } from "../../utils";
|
||||
export default defineComponent({
|
||||
name: "cl-table",
|
||||
|
||||
emits: ["selection-change", "sort-change"],
|
||||
|
||||
props: {
|
||||
// 列配置
|
||||
columns: {
|
||||
@ -39,6 +37,8 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
|
||||
emits: ["selection-change", "sort-change"],
|
||||
|
||||
setup(props, { emit, expose }) {
|
||||
const { crud } = useCore();
|
||||
const { getValue, style } = useTools();
|
||||
|
||||
@ -7,8 +7,6 @@ import { mergeConfig } from "../../utils";
|
||||
export default defineComponent({
|
||||
name: "cl-upsert",
|
||||
|
||||
emits: ["opened", "closed"],
|
||||
|
||||
props: {
|
||||
// 表单项
|
||||
items: {
|
||||
@ -37,6 +35,8 @@ export default defineComponent({
|
||||
onSubmit: Function
|
||||
},
|
||||
|
||||
emits: ["opened", "closed"],
|
||||
|
||||
setup(props, { slots, expose }) {
|
||||
const { crud } = useCore();
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="c">
|
||||
<!-- <el-button @click="submit">submit</el-button> -->
|
||||
{{ Form?.form.t2.name }} - {{ disabled }}
|
||||
{{ form?.t2.name }} - {{ disabled }}
|
||||
<el-input v-model="val" @input="onChange"></el-input>
|
||||
<el-button @click="add">a</el-button>
|
||||
<el-button @click="remove">b</el-button>
|
||||
@ -9,10 +9,10 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import { useForm, useUpsert } from "../hooks";
|
||||
|
||||
const props = defineProps({
|
||||
defineProps({
|
||||
modelValue: Object,
|
||||
title: String,
|
||||
scope: null,
|
||||
@ -27,7 +27,7 @@ const Form = useForm();
|
||||
|
||||
const form = computed(() => Upsert.value?.form);
|
||||
|
||||
const val = ref<string>("");
|
||||
const val = ref("");
|
||||
|
||||
function onChange(val: string) {
|
||||
emit("update:modelValue", val);
|
||||
|
||||
@ -21,7 +21,7 @@ export default defineComponent({
|
||||
const Form = useForm();
|
||||
const Crud = useCrud();
|
||||
|
||||
const Upsert = useUpsert({
|
||||
useUpsert({
|
||||
onOpened(data) {
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
@ -17,10 +17,49 @@ const { refs, setRefs } = useRefs();
|
||||
|
||||
const Upsert = useUpsert({
|
||||
items: [
|
||||
{
|
||||
prop: "user",
|
||||
component: {
|
||||
name: "cl-form-card",
|
||||
props: {
|
||||
label: "用户信息"
|
||||
}
|
||||
},
|
||||
children: [
|
||||
{
|
||||
label: "账号",
|
||||
prop: "account",
|
||||
span: 12,
|
||||
required: true,
|
||||
component: {
|
||||
name: "el-input"
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "密码",
|
||||
prop: "password",
|
||||
span: 12,
|
||||
required: true,
|
||||
component: {
|
||||
name: "el-input",
|
||||
props: {
|
||||
type: "password"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "手机号",
|
||||
prop: "phone",
|
||||
component: {
|
||||
name: "el-input"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "姓名",
|
||||
renderLabel: () => {
|
||||
return <p>1</p>;
|
||||
return <p style="color: green">姓名</p>;
|
||||
},
|
||||
prop: "name",
|
||||
required: true,
|
||||
|
||||
@ -14,6 +14,8 @@ interface Options {
|
||||
item?: any;
|
||||
// 插槽
|
||||
slots?: any;
|
||||
// 子集
|
||||
children?: any[] & any;
|
||||
// 自定义
|
||||
custom?: (vnode: any) => any;
|
||||
// 渲染方式
|
||||
@ -105,7 +107,7 @@ export function parseNode(vnode: any, options: Options): VNode {
|
||||
|
||||
// 渲染节点
|
||||
export function renderNode(vnode: any, options: Options) {
|
||||
const { item, scope, _data, render } = options || {};
|
||||
const { item, scope, children, _data, render } = options || {};
|
||||
|
||||
if (!vnode) {
|
||||
return null;
|
||||
@ -174,8 +176,7 @@ export function renderNode(vnode: any, options: Options) {
|
||||
// jsx 模式
|
||||
if (isObject(vnode)) {
|
||||
if (vnode.name) {
|
||||
const { children } = parseExtensionComponent(vnode);
|
||||
return parseNode(vnode, { ...options, children });
|
||||
return parseNode(vnode, { ...options, children, ...parseExtensionComponent(vnode) });
|
||||
} else {
|
||||
if (options.custom) {
|
||||
return options.custom(vnode);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user