Skip to content

Commit

Permalink
feat: FsComponentRender组件重构
Browse files Browse the repository at this point in the history
修复选择联动示例报错的bug
  • Loading branch information
greper committed Apr 7, 2023
1 parent 5bb75dc commit fb6d77d
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 55 deletions.
13 changes: 7 additions & 6 deletions packages/fast-crud/src/components/crud/fs-cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,23 @@ export default defineComponent({
</span>
);
};
if (props.conditionalRender && props.conditionalRender.match && props.conditionalRender.match(props.scope)) {
const scope = { ...props.scope, props: props.item };
if (props.conditionalRender && props.conditionalRender.match && props.conditionalRender.match(scope)) {
//条件render
return cellContentRender(props.conditionalRender.render(props.scope));
return cellContentRender(props.conditionalRender.render(scope));
} else if (props.slots) {
return cellContentRender(props.slots(props.scope));
return cellContentRender(props.slots(scope));
} else if (props.item.formatter) {
return cellContentRender(props.item.formatter(props.scope));
return cellContentRender(props.item.formatter(scope));
} else if (props.item.cellRender) {
return cellContentRender(props.item.cellRender(props.scope));
return cellContentRender(props.item.cellRender(scope));
} else if (props.item.render) {
console.warn("column.render 配置已废弃,请使用column.cellRender代替");
} else if (computedComponent.value?.name) {
if (computedComponent.value?.show === false) {
return;
}
return <fs-component-render title={title} ref={"targetRef"} {...computedComponent.value} scope={props.scope} />;
return <fs-component-render title={title} ref={"targetRef"} {...computedComponent.value} scope={scope} />;
} else {
return cellContentRender(value);
}
Expand Down
117 changes: 70 additions & 47 deletions packages/fast-crud/src/components/render/fs-component-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import {
resolveComponent,
resolveDynamicComponent,
ref,
defineComponent
defineComponent,
watch,
shallowRef
} from "vue";
import _ from "lodash-es";
import { useUi } from "../../use";
Expand Down Expand Up @@ -78,10 +80,14 @@ export default defineComponent({
/**
* 组件参数,会与attrs合并
*/
props: {}
} as any,
props: {},
/**
* 自定义render
*/
render: {}
},
emits: ["update:dict", "update:modelValue", "mounted"],
setup(props, ctx) {
setup(props: any, ctx) {
const { ui } = useUi();
provide("get:scope", () => {
return props.scope;
Expand All @@ -91,12 +97,13 @@ export default defineComponent({
ctx.emit("mounted", props.scope);
});

const targetRef = ref();
// 带事件的attrs
const allAttrs = computed(() => {
const vModel = props.vModel || "modelValue";
const modelValue = props.modelValue ?? (ui.type === "antdv" ? undefined : null);
const attrs = {
ref: "targetRef",
ref: targetRef,
// scope: props.scope,
// fix element display false bug
[vModel]: modelValue,
Expand Down Expand Up @@ -136,51 +143,57 @@ export default defineComponent({
_.forEach(props.slots, createChildren);
return children;
};
// eslint-disable-next-line vue/no-setup-props-destructure
let inputComp = props.name || ui.input.name;

const inputCompRef = shallowRef();
const isAsyncComponent = ref(false);
if (!htmlTags.includes(inputComp)) {
inputComp = resolveDynamicComponent(inputComp);
if (typeof inputComp === "string") {
inputComp = resolveComponent(inputComp);
}
if (inputComp?.name === "AsyncComponentWrapper") {
//如果是异步组件
isAsyncComponent.value = true;
watch(
() => {
return props.name;
},
(value) => {
let inputComp = value || ui.input.name;
if (!htmlTags.includes(inputComp)) {
inputComp = resolveDynamicComponent(inputComp);
if (typeof inputComp === "string") {
inputComp = resolveComponent(inputComp);
}
if (inputComp?.name === "AsyncComponentWrapper") {
//如果是异步组件
isAsyncComponent.value = true;
}
}
inputCompRef.value = inputComp;
},
{
immediate: true
}
}
);

const childrenRendered = childrenRender;
return {
allAttrs,
isAsyncComponent,
childrenRendered,
inputComp
};
},
methods: {
getTargetRef() {
if (this.isAsyncComponent) {
return this.getTargetRefAsync();

function getTargetRef() {
if (isAsyncComponent.value) {
return getTargetRefAsync();
}
return this.getTargetRefSync();
},
getTargetRefSync() {
return this.$refs.targetRef;
},
return getTargetRefSync();
}
function getTargetRefSync() {
return targetRef.value;
}

//异步获取组件实例,asyncComponent加载需要时间
async getTargetRefAsync() {
const c = this.getTargetRefSync();
async function getTargetRefAsync() {
const c = getTargetRefSync();
if (c != null) {
return c;
}
return new Promise((resolve, reject) => {
this.getTargetRefDelay(resolve, reject, 0);
getTargetRefDelay(resolve, reject, 0);
});
},
getTargetRefDelay(resolve: any, reject: any, count: number) {
}
function getTargetRefDelay(resolve: any, reject: any, count: number) {
setTimeout(() => {
const c = this.getTargetRefSync();
const c = getTargetRefSync();
if (c != null) {
resolve(c);
return;
Expand All @@ -190,16 +203,26 @@ export default defineComponent({
reject(new Error("异步组件加载超时"));
return;
}
this.getTargetRefDelay(resolve, reject, count);
getTargetRefDelay(resolve, reject, count);
}, 200);
}
},
render() {
//merge 必须写在这里
const merged = mergeProps(this.allAttrs, this.$attrs);
mergeEventHandles(merged, "onChange");
mergeEventHandles(merged, "onBlur");
const inputComp = this.inputComp;
return <inputComp {...merged}>{this.childrenRendered()}</inputComp>;

ctx.expose({
props,
getTargetRefSync,
getTargetRef
});

return () => {
//merge 必须写在这里
const merged = mergeProps(allAttrs.value, ctx.attrs);
mergeEventHandles(merged, "onChange");
mergeEventHandles(merged, "onBlur");
if (props.render) {
return props.render(merged);
}
const inputComp = inputCompRef.value;
return <inputComp {...merged}>{childrenRendered()}</inputComp>;
};
}
});
6 changes: 4 additions & 2 deletions packages/fast-crud/src/components/search/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,16 @@ export default defineComponent({
} else if (item.component && item.component.show !== false) {
defaultSlot = (
<fs-component-render
ref={(value: any) => {
componentRenderRefs.value[key] = value;
}}
model-value={get(form, key)}
{...item.component}
scope={buildFieldContext(key)}
onUpdate:modelValue={_onUpdateModelValue}
onInput={_onInput}
/>
);
componentRenderRefs.value[key] = defaultSlot;
}
return ui.formItem.render({
Expand Down Expand Up @@ -307,7 +309,7 @@ export default defineComponent({
}
function getComponentRef(key: string): any {
return getComponentRenderRef(key)?.$refs?.targetRef;
return getComponentRenderRef(key)?.getTargetRef();
}
function getContextFn(): SearchEventContext {
Expand Down

0 comments on commit fb6d77d

Please sign in to comment.