mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-08 01:06:41 +08:00
更新 FormRender 组件,使用 RenderProps 类型替代原有的 config 类型,并增强渲染逻辑以支持 html 和 text 属性
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { RenderProps } from '@/api/types'
|
||||||
import { h, resolveComponent, defineProps } from 'vue'
|
import { h, resolveComponent, defineProps } from 'vue'
|
||||||
|
|
||||||
// 定义 props
|
// 定义 props
|
||||||
const props = defineProps<{
|
defineProps<{
|
||||||
config: Record<string, any> // JSON 配置
|
config: RenderProps // JSON 配置
|
||||||
model: Record<string, any> // 数据模型
|
model: Record<string, any> // 数据模型
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ const renderSlotContent = (slotContent: any, model: any, slotScope: any) => {
|
|||||||
* @returns 渲染的组件 VNode
|
* @returns 渲染的组件 VNode
|
||||||
*/
|
*/
|
||||||
const renderComponent = (config: any, model: any, slotScope: any = {}) => {
|
const renderComponent = (config: any, model: any, slotScope: any = {}) => {
|
||||||
const { component, props: componentProps = {}, content = [], slots = {} } = config
|
const { component, props: componentProps = {}, content = [], slots = {}, html, text } = config
|
||||||
|
|
||||||
// 动态解析组件
|
// 动态解析组件
|
||||||
const Component = resolveComponent(component)
|
const Component = resolveComponent(component)
|
||||||
@@ -82,10 +83,30 @@ const renderComponent = (config: any, model: any, slotScope: any = {}) => {
|
|||||||
slotNodes[slotName] = (slotScopeData: any) => renderSlotContent(slotContent, model, slotScopeData)
|
slotNodes[slotName] = (slotScopeData: any) => renderSlotContent(slotContent, model, slotScopeData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 渲染组件内容
|
||||||
|
const renderContent = () => {
|
||||||
|
// 如果配置了 `html`,直接渲染为 HTML 内容
|
||||||
|
if (html) {
|
||||||
|
return h('div', { innerHTML: typeof html === 'string' ? html : model[html] })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果配置了 `text`,直接渲染为文本内容
|
||||||
|
if (text) {
|
||||||
|
return typeof text === 'string' ? text : model[text]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果配置了 `content`,递归渲染子组件
|
||||||
|
if (Array.isArray(content)) {
|
||||||
|
return content.map((childConfig: any) => renderComponent(childConfig, model))
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
// 渲染组件
|
// 渲染组件
|
||||||
return h(Component, parsedProps, {
|
return h(Component, parsedProps, {
|
||||||
...slotNodes,
|
...slotNodes,
|
||||||
default: () => content.map((childConfig: any) => renderComponent(childConfig, model)),
|
default: renderContent, // 确保默认插槽只包含当前组件的内容
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -93,10 +114,6 @@ const renderComponent = (config: any, model: any, slotScope: any = {}) => {
|
|||||||
<template>
|
<template>
|
||||||
<!-- 调用递归渲染函数 -->
|
<!-- 调用递归渲染函数 -->
|
||||||
<div>
|
<div>
|
||||||
<Component v-if="config.html" :is="config.component" v-bind="config.props" v-html="config.html" />
|
<Component :is="renderComponent(config, model)" />
|
||||||
<Component v-else-if="config.text" :is="config.component" v-bind="config.props">
|
|
||||||
{{ config.text }}
|
|
||||||
</Component>
|
|
||||||
<Component v-else :is="renderComponent(config, model)" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user