-
Notifications
You must be signed in to change notification settings - Fork 319
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' | ||
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. 如果这样修改可能会对现有业务造成影响,你这操作相当于包了一层组件转发下props,能不能通过某一个全局配置可以让用户自己选择是否开启这个功能,不要对存量业务造成影响 |
||
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
unwrap
method correctly handles all possible types of reactive objects to avoid unexpected behavior.