diff --git a/examples/sites/demos/pc/app/config-provider/base-composition-api.vue b/examples/sites/demos/pc/app/config-provider/base-composition-api.vue
index 6919fd0907..bf629317dd 100644
--- a/examples/sites/demos/pc/app/config-provider/base-composition-api.vue
+++ b/examples/sites/demos/pc/app/config-provider/base-composition-api.vue
@@ -53,6 +53,9 @@ const design = {
icons: {
warning: iconWarningTriangle()
},
+ props: {
+ center: true
+ },
/**
*
* @param {*} props 组件属性集合
diff --git a/examples/sites/demos/pc/app/config-provider/base.vue b/examples/sites/demos/pc/app/config-provider/base.vue
index f14e29ba86..6b9a61b282 100644
--- a/examples/sites/demos/pc/app/config-provider/base.vue
+++ b/examples/sites/demos/pc/app/config-provider/base.vue
@@ -60,6 +60,9 @@ export default {
}
},
Alert: {
+ props: {
+ center: true
+ },
icons: {
warning: iconWarningTriangle()
},
diff --git a/examples/sites/demos/pc/app/config-provider/basic.spec.ts b/examples/sites/demos/pc/app/config-provider/basic.spec.ts
index 8329c67a10..09a79e567d 100644
--- a/examples/sites/demos/pc/app/config-provider/basic.spec.ts
+++ b/examples/sites/demos/pc/app/config-provider/basic.spec.ts
@@ -4,8 +4,11 @@ test('测试自定义事件', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('config-provider#base')
- // 验证自定义方法
const demo = page.locator('#base')
+ // 验证文字居中
+ await expect(demo.locator('.tiny-alert')).toHaveCSS('justify-content', 'center')
+
+ // 验证自定义方法
await demo.locator('.tiny-config-provider .tiny-alert > .tiny-alert__close').click()
await page.waitForTimeout(500)
await expect(page.locator('.tiny-modal > .tiny-modal__box').nth(1)).toHaveText('触发自定方法')
diff --git a/examples/sites/demos/pc/app/config-provider/webdoc/config-provider.js b/examples/sites/demos/pc/app/config-provider/webdoc/config-provider.js
index f49b70845f..3301a555c1 100644
--- a/examples/sites/demos/pc/app/config-provider/webdoc/config-provider.js
+++ b/examples/sites/demos/pc/app/config-provider/webdoc/config-provider.js
@@ -12,9 +12,9 @@ export default {
},
desc: {
'zh-CN':
- '可通过 design
属性设置自定义不同设计规范的图标和逻辑,例如:全局配置 Form 表单组件的必填星号是否默认显示、Button 组件的点击后的禁用时间和是否默认圆角。',
+ '通过 design
属性可以自定义不同设计规范的图标和逻辑。从 3.23.0 版本开始,支持全局配置组件的任意 props
属性(仅支持双层组件),例如:可以全局配置 Form 组件必填项星号的默认显示状态、Button 组件的点击防抖时间以及是否默认显示圆角等。',
'en-US':
- 'Icons and logic for different design specifications can be customized through the design
attribute configuration.'
+ 'You can use the design
property to set custom icons and logic for different design specifications, starting from version 3.23.0, the global configuration component (only supports double-layer components) supports the function of any props
attribute, for example: the default display of the required star of the global configuration Form form component, the disabled time after the click of the Button component, and whether the default roundness is enabled.'
},
codeFiles: ['base.vue']
},
diff --git a/packages/vue-common/src/adapter/vue2.7/index.ts b/packages/vue-common/src/adapter/vue2.7/index.ts
index b1faf1fc07..ef9bf7be62 100644
--- a/packages/vue-common/src/adapter/vue2.7/index.ts
+++ b/packages/vue-common/src/adapter/vue2.7/index.ts
@@ -26,18 +26,32 @@ export const renderComponent = ({
view = null as any,
component = null as any,
props,
+ customDesignProps,
context: { attrs, listeners: on, slots },
extend = {}
}) => {
return () =>
hooks.h(
(view && view.value) || component,
- Object.assign({ props, attrs, [extend.isSvg ? 'nativeOn' : 'on']: on, scopedSlots: { ...slots } }, extend)
+ Object.assign(
+ {
+ props: { ...props, ...customDesignProps },
+ attrs,
+ [extend.isSvg ? 'nativeOn' : 'on']: on,
+ scopedSlots: { ...slots }
+ },
+ extend
+ )
)
}
export const rootConfig = () => hooks.getCurrentInstance()?.proxy.$root
+export const getCustomProps = () => {
+ const instance = hooks.getCurrentInstance()?.proxy
+ return instance?.$options?.propsData || {}
+}
+
export const getComponentName = () => {
// 此处组件最多为两层组件,所以对多获取到父级组件即可
const instance = hooks.getCurrentInstance()
diff --git a/packages/vue-common/src/adapter/vue2/index.ts b/packages/vue-common/src/adapter/vue2/index.ts
index ba801ac572..1dee08a22e 100644
--- a/packages/vue-common/src/adapter/vue2/index.ts
+++ b/packages/vue-common/src/adapter/vue2/index.ts
@@ -34,6 +34,7 @@ export const renderComponent = ({
view = null as any,
component = null as any,
props,
+ customDesignProps,
context: { attrs, listeners: on, slots },
extend = {}
}) => {
@@ -41,7 +42,13 @@ export const renderComponent = ({
hooks.h(
(view && view.value) || component,
Object.assign(
- { props, attrs, [extend.isSvg ? 'nativeOn' : 'on']: on, ref: 'modeTemplate', scopedSlots: { ...slots } },
+ {
+ props: { ...props, ...customDesignProps },
+ attrs,
+ [extend.isSvg ? 'nativeOn' : 'on']: on,
+ ref: 'modeTemplate',
+ scopedSlots: { ...slots }
+ },
extend
)
)
@@ -49,6 +56,11 @@ export const renderComponent = ({
export const rootConfig = () => hooks.getCurrentInstance()?.proxy.$root
+export const getCustomProps = () => {
+ const instance = hooks.getCurrentInstance()?.proxy
+ return instance?.$options?.propsData || {}
+}
+
export const getComponentName = () => {
// 此处组件最多为两层组件,所以对多获取到父级组件即可
const instance = hooks.getCurrentInstance()
diff --git a/packages/vue-common/src/adapter/vue3/index.ts b/packages/vue-common/src/adapter/vue3/index.ts
index cfb1e4ea08..72b31830c6 100644
--- a/packages/vue-common/src/adapter/vue3/index.ts
+++ b/packages/vue-common/src/adapter/vue3/index.ts
@@ -26,10 +26,16 @@ export const renderComponent = ({
view = undefined as any,
component = undefined as any,
props,
+ customDesignProps,
context: { attrs, slots },
extend = {}
}) => {
- return () => hooks.h((view && view.value) || component, { ref: 'modeTemplate', ...props, ...attrs, ...extend }, slots)
+ return () =>
+ hooks.h(
+ (view && view.value) || component,
+ { ref: 'modeTemplate', ...props, ...attrs, ...customDesignProps, ...extend },
+ slots
+ )
}
export const rootConfig = (context) => {
@@ -38,6 +44,11 @@ export const rootConfig = (context) => {
return instance?.appContext.config.globalProperties
}
+export const getCustomProps = () => {
+ const instance = hooks.getCurrentInstance()
+ return instance?.vnode?.props || {}
+}
+
export const getComponentName = () => {
// 此处组件最多为两层组件,所以对多获取到父级组件即可
const instance = hooks.getCurrentInstance()
diff --git a/packages/vue-common/src/index.ts b/packages/vue-common/src/index.ts
index 0556b9d4e6..926047c73e 100644
--- a/packages/vue-common/src/index.ts
+++ b/packages/vue-common/src/index.ts
@@ -16,6 +16,7 @@ import {
tools,
useRouter,
getComponentName,
+ getCustomProps,
isVnode
} from './adapter'
import { t } from '@opentiny/vue-locale'
@@ -122,19 +123,6 @@ const resolveChartTheme = (props, context) => {
return tinyChartTheme
}
-export const $setup = ({ props, context, template, extend = {} }) => {
- const mode = resolveMode(props, context)
- const view = hooks.computed(() => {
- if (typeof props.tiny_template !== 'undefined') return props.tiny_template
-
- const component = template(mode, props)
-
- return typeof component === 'function' ? defineAsyncComponent(component) : component
- })
-
- return renderComponent({ view, props, context, extend })
-}
-
// 提供给没有renderless层的组件使用(比如TinyVuePlus组件)
export const design = {
configKey: Symbol('designConfigKey'),
@@ -168,17 +156,55 @@ export const customDesignConfig: CustomDesignConfig = {
twMerge: () => ''
}
-export const mergeClass = (...cssClasses) => customDesignConfig.twMerge(stringifyCssClass(cssClasses))
-
-export const setup = ({ props, context, renderless, api, extendOptions = {}, mono = false, classes = {} }) => {
- const render = typeof props.tiny_renderless === 'function' ? props.tiny_renderless : renderless
-
+const getDesignConfig = () => {
// 获取组件级配置和全局配置(inject需要带有默认值,否则控制台会报警告)
let globalDesignConfig: DesignConfig = customDesignConfig.designConfig || hooks.inject(design.configKey, {})
+
// globalDesignConfig 可能是响应式对象,比如 computed
globalDesignConfig = globalDesignConfig?.value || globalDesignConfig || {}
const designConfig = globalDesignConfig?.components?.[getComponentName().replace($prefix, '')]
+ return {
+ designConfig,
+ globalDesignConfig
+ }
+}
+
+export const $setup = ({ props: propData, context, template, extend = {} }) => {
+ const mode = resolveMode(propData, context)
+ const view = hooks.computed(() => {
+ if (typeof propData.tiny_template !== 'undefined') return propData.tiny_template
+
+ const component = template(mode, propData)
+
+ return typeof component === 'function' ? defineAsyncComponent(component) : component
+ })
+
+ const { designConfig } = getDesignConfig()
+ const customDesignProps = {}
+
+ const designProps = designConfig?.props
+
+ if (designProps) {
+ // 获取用户传递的props
+ const customProps = getCustomProps()
+
+ Object.keys(designProps).forEach((key) => {
+ // 用户没有配置的属性才进行覆盖
+ if (!Object.prototype.hasOwnProperty.call(customProps, key)) {
+ customDesignProps[key] = designProps[key]
+ }
+ })
+ }
+
+ return renderComponent({ view, props: propData, customDesignProps, context, extend })
+}
+
+export const mergeClass = (...cssClasses) => customDesignConfig.twMerge(stringifyCssClass(cssClasses))
+
+export const setup = ({ props, context, renderless, api, extendOptions = {}, mono = false, classes = {} }) => {
+ const render = typeof props.tiny_renderless === 'function' ? props.tiny_renderless : renderless
+ const { designConfig, globalDesignConfig } = getDesignConfig()
const utils = {
$prefix,
t,
diff --git a/packages/vue/package.json b/packages/vue/package.json
index d0b9717ecb..23287a174b 100644
--- a/packages/vue/package.json
+++ b/packages/vue/package.json
@@ -237,4 +237,4 @@
"build": "pnpm -w build:ui",
"postversion": "pnpm build"
}
-}
+}
\ No newline at end of file