-
Notifications
You must be signed in to change notification settings - Fork 330
Props hoc #3084
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Props hoc #3084
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| import Vue from 'vue' | ||
| import { design, $prefix } from '../../index' | ||
|
|
||
| export default function DesignConfigPropsHOC(BaseComponent) { | ||
| return Vue.extend({ | ||
| name: 'DesignConfigHOC', | ||
| functional: false, | ||
| inject: { | ||
| globalDesignConfig: { | ||
| from: design.configKey, | ||
| default: () => ({}) | ||
| } | ||
| }, | ||
| created() { | ||
| // 暴露实例方法 | ||
| this.$watch( | ||
| () => this.innerRef, | ||
| (val) => { | ||
| if (val) { | ||
| Object.keys(val).forEach((key) => { | ||
| if (!(key in this)) { | ||
| this[key] = val[key] | ||
| } | ||
| }) | ||
| } | ||
| } | ||
| ) | ||
| }, | ||
| data() { | ||
| return { | ||
| innerRef: null | ||
| } | ||
| }, | ||
| computed: { | ||
| componentName() { | ||
| const rawName = BaseComponent.name || BaseComponent.options.name | ||
| return rawName.replace($prefix, '') | ||
| }, | ||
| mergedProps() { | ||
| // 处理响应式配置 | ||
| const globalConfig = this.unwrap(this.globalDesignConfig) | ||
| const componentConfig = globalConfig.components?.[this.componentName] || {} | ||
| return { | ||
| ...componentConfig.props, | ||
| ...this.$attrs | ||
| } | ||
| } | ||
| }, | ||
| methods: { | ||
| // 解包可能存在的响应式对象 | ||
| unwrap(config) { | ||
| if (config && typeof config === 'object' && 'value' in config) { | ||
| return config.value | ||
| } | ||
| return config || {} | ||
| } | ||
| }, | ||
| render(h) { | ||
| return h( | ||
| BaseComponent, | ||
| { | ||
| ref: (el) => { | ||
| this.innerRef = el | ||
| }, | ||
| attrs: this.mergedProps, | ||
| on: this.$listeners, | ||
| scopedSlots: this.$scopedSlots | ||
| }, | ||
| this.$slots.default | ||
| ) | ||
| } | ||
| }) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| import Vue from 'vue' | ||
| import { design, $prefix } from '../../index' | ||
|
|
||
| export default function DesignConfigPropsHOC(BaseComponent) { | ||
| return Vue.extend({ | ||
| name: 'DesignConfigHOC', | ||
| functional: false, | ||
| inject: { | ||
| globalDesignConfig: { | ||
| from: design.configKey, | ||
| default: () => ({}) | ||
| } | ||
| }, | ||
| created() { | ||
| // 暴露实例方法 | ||
| this.$watch( | ||
| () => this.innerRef, | ||
| (val) => { | ||
| if (val) { | ||
| Object.keys(val).forEach((key) => { | ||
| if (!(key in this)) { | ||
| this[key] = val[key] | ||
| } | ||
| }) | ||
| } | ||
| } | ||
| ) | ||
| }, | ||
| data() { | ||
| return { | ||
| innerRef: null | ||
| } | ||
| }, | ||
| computed: { | ||
| componentName() { | ||
| const rawName = BaseComponent.name || BaseComponent.options.name | ||
| return rawName.replace($prefix, '') | ||
| }, | ||
| mergedProps() { | ||
| // 处理响应式配置 | ||
| const globalConfig = this.unwrap(this.globalDesignConfig) | ||
| const componentConfig = globalConfig.components?.[this.componentName] || {} | ||
| return { | ||
| ...componentConfig.props, | ||
| ...this.$attrs | ||
| } | ||
| } | ||
| }, | ||
| methods: { | ||
| // 解包可能存在的响应式对象 | ||
| unwrap(config) { | ||
| if (config && typeof config === 'object' && 'value' in config) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure that the |
||
| return config.value | ||
| } | ||
| return config || {} | ||
| } | ||
| }, | ||
| render(h) { | ||
| return h( | ||
| BaseComponent, | ||
| { | ||
| ref: (el) => { | ||
| this.innerRef = el | ||
| }, | ||
| attrs: this.mergedProps, | ||
| on: this.$listeners, | ||
| scopedSlots: this.$scopedSlots | ||
| }, | ||
| this.$slots.default | ||
| ) | ||
| } | ||
| }) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import { type SetupContext } from 'vue' | ||
| import { design, hooks, $prefix } from '../../index' | ||
| import { getComponentName } from '../index' | ||
|
|
||
| // 修改组件 props ,注入 Design Config | ||
| export default function DesignConfigPropsHOC(BaseComponent: any) { | ||
| return { | ||
| ...BaseComponent, | ||
| props: {}, | ||
| setup(props, { attrs, slots, expose }: SetupContext) { | ||
| const innerRef = hooks.ref() | ||
| // 获取组件级配置和全局配置(inject需要带有默认值,否则控制台会报警告) | ||
| let globalDesignConfig = hooks.inject(design.configKey, {}) | ||
| // globalDesignConfig 可能是响应式对象,比如 computed | ||
| globalDesignConfig = globalDesignConfig?.value || globalDesignConfig || {} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure that the |
||
| const designConfig = globalDesignConfig?.components?.[getComponentName().replace($prefix, '')] | ||
| const designConfigProps = designConfig?.props || {} | ||
| const mergedProps = { ...designConfigProps, ...attrs } | ||
|
|
||
| expose( | ||
| new Proxy( | ||
| {}, | ||
| { | ||
| get(_target, key) { | ||
| return innerRef.value?.[key] | ||
| }, | ||
| has(_target, key) { | ||
| return innerRef.value?.[key] | ||
| } | ||
| } | ||
| ) | ||
| ) | ||
|
|
||
| return () => { | ||
| return ( | ||
| <BaseComponent {...mergedProps} ref={innerRef}> | ||
| {slots} | ||
| </BaseComponent> | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,7 @@ | |
| * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS. | ||
| * | ||
| */ | ||
| import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common' | ||
| import { $props, $prefix, $setup, WithDesignConfigPropsDefineComponent as defineComponent } from '@opentiny/vue-common' | ||
|
||
| import template from 'virtual-template?pc|mobile-first' | ||
|
|
||
| export const buttonProps = { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure that the
unwrapmethod correctly handles all possible types of reactive objects to avoid unexpected behavior.