diff --git a/packages/button/index.js b/packages/button/index.js index f8f824d38..b2d87fc59 100644 --- a/packages/button/index.js +++ b/packages/button/index.js @@ -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 ? ( diff --git a/packages/contact-card/index.js b/packages/contact-card/index.js index 5021dc684..bd9317609 100644 --- a/packages/contact-card/index.js +++ b/packages/contact-card/index.js @@ -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') diff --git a/packages/contact-list/index.js b/packages/contact-list/index.js index 1508e040d..3ed828453 100644 --- a/packages/contact-list/index.js +++ b/packages/contact-list/index.js @@ -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 ( -
+
{List} diff --git a/packages/nav-bar/index.js b/packages/nav-bar/index.js index bc2f04089..c923c8ac8 100644 --- a/packages/nav-bar/index.js +++ b/packages/nav-bar/index.js @@ -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({
{slots.left || [ diff --git a/packages/submit-bar/index.js b/packages/submit-bar/index.js index 7210fc77b..d49eb2613 100644 --- a/packages/submit-bar/index.js +++ b/packages/submit-bar/index.js @@ -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 ( -
+
{slots.top} {(slots.tip || tip) && (
diff --git a/packages/switch-cell/index.js b/packages/switch-cell/index.js index 4db47370f..a88a50974 100644 --- a/packages/switch-cell/index.js +++ b/packages/switch-cell/index.js @@ -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 ( - + ); diff --git a/packages/utils/functional.ts b/packages/utils/functional.ts new file mode 100644 index 000000000..aba54550e --- /dev/null +++ b/packages/utils/functional.ts @@ -0,0 +1,33 @@ +import { RenderContext, VNodeData } from 'vue'; + +type ObjectIndex = { + [key: string]: any; +}; + +type Context = RenderContext & { data: VNodeData & ObjectIndex }; + +type InheritContext = Partial & 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 + ); +} diff --git a/packages/utils/use/sfc.js b/packages/utils/use/sfc.js deleted file mode 100644 index 7d7f4340f..000000000 --- a/packages/utils/use/sfc.js +++ /dev/null @@ -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; -}; diff --git a/packages/utils/use/sfc.ts b/packages/utils/use/sfc.ts new file mode 100644 index 000000000..ee38fd201 --- /dev/null +++ b/packages/utils/use/sfc.ts @@ -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 & { + 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: 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; +};