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 { use } from '../utils';
|
||||||
|
import { inheritContext } from '../utils/functional';
|
||||||
import Loading from '../loading';
|
import Loading from '../loading';
|
||||||
|
|
||||||
const [sfc, bem] = use('button');
|
const [sfc, bem] = use('button');
|
||||||
@ -30,7 +31,7 @@ export default sfc({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render(h, context, inherit) {
|
render(h, context) {
|
||||||
const { props, listeners } = context;
|
const { props, listeners } = context;
|
||||||
const { type, disabled, loading } = props;
|
const { type, disabled, loading } = props;
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ export default sfc({
|
|||||||
}
|
}
|
||||||
])}
|
])}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
{...inherit}
|
{...inheritContext(context)}
|
||||||
>
|
>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<Loading size="20px" color={type === 'default' ? undefined : ''} />
|
<Loading size="20px" color={type === 'default' ? undefined : ''} />
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { use } from '../utils';
|
import { use } from '../utils';
|
||||||
|
import { inheritContext } from '../utils/functional';
|
||||||
import Cell from '../cell';
|
import Cell from '../cell';
|
||||||
|
|
||||||
const [sfc, bem, t] = use('contact-card');
|
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 { props, listeners } = context;
|
||||||
const { type, editable } = props;
|
const { type, editable } = props;
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ export default sfc({
|
|||||||
listeners.click(event);
|
listeners.click(event);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
{...inherit}
|
{...inheritContext(context)}
|
||||||
>
|
>
|
||||||
{type === 'add'
|
{type === 'add'
|
||||||
? props.addText || t('addText')
|
? props.addText || t('addText')
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { use, noop } from '../utils';
|
import { use, noop } from '../utils';
|
||||||
|
import { inheritContext } from '../utils/functional';
|
||||||
import Icon from '../icon';
|
import Icon from '../icon';
|
||||||
import Cell from '../cell';
|
import Cell from '../cell';
|
||||||
import Button from '../button';
|
import Button from '../button';
|
||||||
@ -16,7 +17,7 @@ export default sfc({
|
|||||||
addText: String
|
addText: String
|
||||||
},
|
},
|
||||||
|
|
||||||
render(h, context, inherit) {
|
render(h, context) {
|
||||||
const { props, listeners } = context;
|
const { props, listeners } = context;
|
||||||
|
|
||||||
const List = props.list.map((item, index) => (
|
const List = props.list.map((item, index) => (
|
||||||
@ -50,7 +51,7 @@ export default sfc({
|
|||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={bem()} {...inherit}>
|
<div class={bem()} {...inheritContext(context)}>
|
||||||
<RadioGroup value={props.value} class={bem('group')}>
|
<RadioGroup value={props.value} class={bem('group')}>
|
||||||
{List}
|
{List}
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { use, noop } from '../utils';
|
import { use, noop } from '../utils';
|
||||||
|
import { inheritContext } from '../utils/functional';
|
||||||
import Icon from '../icon';
|
import Icon from '../icon';
|
||||||
|
|
||||||
const [sfc, bem] = use('nav-bar');
|
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 { props, listeners } = context;
|
||||||
const slots = context.slots();
|
const slots = context.slots();
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ export default sfc({
|
|||||||
<div
|
<div
|
||||||
class={[bem({ fixed: props.fixed }), { 'van-hairline--bottom': props.border }]}
|
class={[bem({ fixed: props.fixed }), { 'van-hairline--bottom': props.border }]}
|
||||||
style={{ zIndex: props.zIndex }}
|
style={{ zIndex: props.zIndex }}
|
||||||
{...inherit}
|
{...inheritContext(context)}
|
||||||
>
|
>
|
||||||
<div class={bem('left')} onClick={listeners['click-left'] || noop}>
|
<div class={bem('left')} onClick={listeners['click-left'] || noop}>
|
||||||
{slots.left || [
|
{slots.left || [
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { use, noop } from '../utils';
|
import { use, noop } from '../utils';
|
||||||
|
import { inheritContext } from '../utils/functional';
|
||||||
import Button from '../button';
|
import Button from '../button';
|
||||||
|
|
||||||
const [sfc, bem, t] = use('submit-bar');
|
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 { props, listeners } = context;
|
||||||
const { tip, price } = props;
|
const { tip, price } = props;
|
||||||
const slots = context.slots();
|
const slots = context.slots();
|
||||||
const hasPrice = typeof price === 'number';
|
const hasPrice = typeof price === 'number';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={bem()} {...inherit}>
|
<div class={bem()} {...inheritContext(context)}>
|
||||||
{slots.top}
|
{slots.top}
|
||||||
{(slots.tip || tip) && (
|
{(slots.tip || tip) && (
|
||||||
<div class={bem('tip')}>
|
<div class={bem('tip')}>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { use } from '../utils';
|
import { use } from '../utils';
|
||||||
|
import { inheritContext } from '../utils/functional';
|
||||||
import Cell from '../cell';
|
import Cell from '../cell';
|
||||||
import Switch from '../switch';
|
import Switch from '../switch';
|
||||||
import SwitchMixin from '../mixins/switch';
|
import SwitchMixin from '../mixins/switch';
|
||||||
@ -19,11 +20,11 @@ export default sfc({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render(h, context, inherit) {
|
render(h, context) {
|
||||||
const { props } = context;
|
const { props } = context;
|
||||||
|
|
||||||
return (
|
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 }} />
|
<Switch {...{ props, on: context.listeners }} />
|
||||||
</Cell>
|
</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