mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[improvement] functional inherit context (#2716)
This commit is contained in:
parent
9947ab00e8
commit
0bf4a9e799
@ -1,4 +1,5 @@
|
||||
import { use } from '../utils';
|
||||
import { inheritContext } from '../utils/functional';
|
||||
import Loading from '../loading';
|
||||
|
||||
const [sfc, bem] = use('button');
|
||||
@ -30,7 +31,7 @@ export default sfc({
|
||||
}
|
||||
},
|
||||
|
||||
render(h, context, inherit) {
|
||||
render(h, context) {
|
||||
const { props, listeners } = context;
|
||||
const { type, disabled, loading } = props;
|
||||
|
||||
@ -58,7 +59,7 @@ export default sfc({
|
||||
}
|
||||
])}
|
||||
onClick={onClick}
|
||||
{...inherit}
|
||||
{...inheritContext(context)}
|
||||
>
|
||||
{loading ? (
|
||||
<Loading size="20px" color={type === 'default' ? undefined : ''} />
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { use } from '../utils';
|
||||
import { inheritContext } from '../utils/functional';
|
||||
import Cell from '../cell';
|
||||
|
||||
const [sfc, bem, t] = use('contact-card');
|
||||
@ -20,7 +21,7 @@ export default sfc({
|
||||
}
|
||||
},
|
||||
|
||||
render(h, context, inherit) {
|
||||
render(h, context) {
|
||||
const { props, listeners } = context;
|
||||
const { type, editable } = props;
|
||||
|
||||
@ -37,7 +38,7 @@ export default sfc({
|
||||
listeners.click(event);
|
||||
}
|
||||
}}
|
||||
{...inherit}
|
||||
{...inheritContext(context)}
|
||||
>
|
||||
{type === 'add'
|
||||
? props.addText || t('addText')
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { use, noop } from '../utils';
|
||||
import { inheritContext } from '../utils/functional';
|
||||
import Icon from '../icon';
|
||||
import Cell from '../cell';
|
||||
import Button from '../button';
|
||||
@ -16,7 +17,7 @@ export default sfc({
|
||||
addText: String
|
||||
},
|
||||
|
||||
render(h, context, inherit) {
|
||||
render(h, context) {
|
||||
const { props, listeners } = context;
|
||||
|
||||
const List = props.list.map((item, index) => (
|
||||
@ -50,7 +51,7 @@ export default sfc({
|
||||
));
|
||||
|
||||
return (
|
||||
<div class={bem()} {...inherit}>
|
||||
<div class={bem()} {...inheritContext(context)}>
|
||||
<RadioGroup value={props.value} class={bem('group')}>
|
||||
{List}
|
||||
</RadioGroup>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { use, noop } from '../utils';
|
||||
import { inheritContext } from '../utils/functional';
|
||||
import Icon from '../icon';
|
||||
|
||||
const [sfc, bem] = use('nav-bar');
|
||||
@ -22,7 +23,7 @@ export default sfc({
|
||||
}
|
||||
},
|
||||
|
||||
render(h, context, inherit) {
|
||||
render(h, context) {
|
||||
const { props, listeners } = context;
|
||||
const slots = context.slots();
|
||||
|
||||
@ -30,7 +31,7 @@ export default sfc({
|
||||
<div
|
||||
class={[bem({ fixed: props.fixed }), { 'van-hairline--bottom': props.border }]}
|
||||
style={{ zIndex: props.zIndex }}
|
||||
{...inherit}
|
||||
{...inheritContext(context)}
|
||||
>
|
||||
<div class={bem('left')} onClick={listeners['click-left'] || noop}>
|
||||
{slots.left || [
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { use, noop } from '../utils';
|
||||
import { inheritContext } from '../utils/functional';
|
||||
import Button from '../button';
|
||||
|
||||
const [sfc, bem, t] = use('submit-bar');
|
||||
@ -26,14 +27,14 @@ export default sfc({
|
||||
}
|
||||
},
|
||||
|
||||
render(h, context, inherit) {
|
||||
render(h, context) {
|
||||
const { props, listeners } = context;
|
||||
const { tip, price } = props;
|
||||
const slots = context.slots();
|
||||
const hasPrice = typeof price === 'number';
|
||||
|
||||
return (
|
||||
<div class={bem()} {...inherit}>
|
||||
<div class={bem()} {...inheritContext(context)}>
|
||||
{slots.top}
|
||||
{(slots.tip || tip) && (
|
||||
<div class={bem('tip')}>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { use } from '../utils';
|
||||
import { inheritContext } from '../utils/functional';
|
||||
import Cell from '../cell';
|
||||
import Switch from '../switch';
|
||||
import SwitchMixin from '../mixins/switch';
|
||||
@ -19,11 +20,11 @@ export default sfc({
|
||||
}
|
||||
},
|
||||
|
||||
render(h, context, inherit) {
|
||||
render(h, context) {
|
||||
const { props } = context;
|
||||
|
||||
return (
|
||||
<Cell center title={props.title} border={props.border} class={bem()} {...inherit}>
|
||||
<Cell center title={props.title} border={props.border} class={bem()} {...inheritContext(context)}>
|
||||
<Switch {...{ props, on: context.listeners }} />
|
||||
</Cell>
|
||||
);
|
||||
|
33
packages/utils/functional.ts
Normal file
33
packages/utils/functional.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { RenderContext, VNodeData } from 'vue';
|
||||
|
||||
type ObjectIndex = {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
type Context = RenderContext & { data: VNodeData & ObjectIndex };
|
||||
|
||||
type InheritContext = Partial<VNodeData> & ObjectIndex;
|
||||
|
||||
const inheritKey = [
|
||||
'style',
|
||||
'class',
|
||||
'attrs',
|
||||
'nativeOn',
|
||||
'directives',
|
||||
'staticClass',
|
||||
'staticStyle'
|
||||
];
|
||||
|
||||
const mapInheritKey: ObjectIndex = { nativeOn: 'on' };
|
||||
|
||||
export function inheritContext(context: Context): InheritContext {
|
||||
return inheritKey.reduce(
|
||||
(obj, key) => {
|
||||
if (context.data[key]) {
|
||||
obj[mapInheritKey[key] || key] = context.data[key];
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
{} as InheritContext
|
||||
);
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/**
|
||||
* Create a basic component with common options
|
||||
*/
|
||||
import '../../locale';
|
||||
import { camelize } from '..';
|
||||
import SlotsMixin from '../../mixins/slots';
|
||||
|
||||
const arrayProp = {
|
||||
type: Array,
|
||||
default: () => []
|
||||
};
|
||||
|
||||
const numberProp = {
|
||||
type: Number,
|
||||
default: 0
|
||||
};
|
||||
|
||||
function defaultProps(props) {
|
||||
Object.keys(props).forEach(key => {
|
||||
if (props[key] === Array) {
|
||||
props[key] = arrayProp;
|
||||
} else if (props[key] === Number) {
|
||||
props[key] = numberProp;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function install(Vue) {
|
||||
const { name } = this;
|
||||
Vue.component(name, this);
|
||||
Vue.component(camelize(`-${name}`), this);
|
||||
}
|
||||
|
||||
const inheritKey = [
|
||||
'style',
|
||||
'class',
|
||||
'attrs',
|
||||
'nativeOn',
|
||||
'directives',
|
||||
'staticClass',
|
||||
'staticStyle'
|
||||
];
|
||||
const mapInheritKey = { nativeOn: 'on' };
|
||||
|
||||
function functional(sfc) {
|
||||
const { render } = sfc;
|
||||
sfc.render = (h, context) => {
|
||||
const inherit = inheritKey.reduce((obj, key) => {
|
||||
if (context.data[key]) {
|
||||
obj[mapInheritKey[key] || key] = context.data[key];
|
||||
}
|
||||
return obj;
|
||||
}, {});
|
||||
return render(h, context, inherit);
|
||||
};
|
||||
}
|
||||
|
||||
export default name => sfc => {
|
||||
sfc.name = name;
|
||||
sfc.install = install;
|
||||
sfc.mixins = sfc.mixins || [];
|
||||
sfc.mixins.push(SlotsMixin);
|
||||
|
||||
if (sfc.props) {
|
||||
defaultProps(sfc.props);
|
||||
}
|
||||
|
||||
if (sfc.functional) {
|
||||
functional(sfc);
|
||||
}
|
||||
|
||||
return sfc;
|
||||
};
|
53
packages/utils/use/sfc.ts
Normal file
53
packages/utils/use/sfc.ts
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Create a basic component with common options
|
||||
*/
|
||||
import '../../locale';
|
||||
import { camelize } from '..';
|
||||
import SlotsMixin from '../../mixins/slots';
|
||||
import Vue, { VueConstructor, ComponentOptions } from 'vue';
|
||||
|
||||
type VantComponentOptions = ComponentOptions<Vue> & {
|
||||
functional?: boolean;
|
||||
install?: (Vue: VueConstructor) => void;
|
||||
};
|
||||
|
||||
const arrayProp = {
|
||||
type: Array,
|
||||
default: () => []
|
||||
};
|
||||
|
||||
const numberProp = {
|
||||
type: Number,
|
||||
default: 0
|
||||
};
|
||||
|
||||
function defaultProps(props: any) {
|
||||
Object.keys(props).forEach(key => {
|
||||
if (props[key] === Array) {
|
||||
props[key] = arrayProp;
|
||||
} else if (props[key] === Number) {
|
||||
props[key] = numberProp;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function install(this: ComponentOptions<Vue>, Vue: VueConstructor) {
|
||||
const { name } = this;
|
||||
if (name) {
|
||||
Vue.component(name, this);
|
||||
Vue.component(camelize(`-${name}`), this);
|
||||
}
|
||||
}
|
||||
|
||||
export default (name: string) => (sfc: VantComponentOptions) => {
|
||||
sfc.name = name;
|
||||
sfc.install = install;
|
||||
sfc.mixins = sfc.mixins || [];
|
||||
sfc.mixins.push(SlotsMixin);
|
||||
|
||||
if (sfc.props) {
|
||||
defaultProps(sfc.props);
|
||||
}
|
||||
|
||||
return sfc;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user