@aspectus/vue-utils
Version:
Vue related utilities that makes development easier.
78 lines (66 loc) • 2.09 kB
JavaScript
/* eslint-disable prefer-object-spread, no-param-reassign, no-unused-expressions */
import { getComponentOptions } from './components';
export const normalizeProps = props => {
if (!props) {
return {};
}
if (Array.isArray(props)) {
const result = {};
props.forEach(key => {
if (typeof key === 'string') {
result[key] = {};
}
});
return result;
}
return Object.assign({}, props);
};
export const mergeMixinProps = (mixins, initial = {}) => {
if (!mixins || !mixins.length) {
return initial;
}
return mixins.reduce((result, mixin) => {
const props = Object.assign(
{},
mergeMixinProps(mixin.mixins, result),
normalizeProps(mixin.props)
);
return Object.assign({}, result, props);
}, initial);
};
export const getProps = Component => {
const options = getComponentOptions(Component);
const props = normalizeProps(options.props);
const mixinProps = mergeMixinProps(options.mixins);
return Object.assign({}, mixinProps, props);
};
export const VALUE_TAG_MAP = {
input: true, textarea: true, option: true, select: true, progress: true,
};
export const DOM_PROP_ATTRS = ['value', 'selected', 'checked', 'muted'];
export const mustBeDOM = (tag, type, attr) => (
(attr === 'value' && VALUE_TAG_MAP[tag]) && type !== 'button' ||
(attr === 'selected' && tag === 'option') ||
(attr === 'checked' && tag === 'input') ||
(attr === 'muted' && tag === 'video')
);
export function internalPropsMagicTransform(tag, context) {
const g = name => (
context.props && context.props[name] ||
context.attrs && context.attrs[name]
);
const tp = g('type');
const hasDom = !!context.domProps;
DOM_PROP_ATTRS.forEach(attr => {
if (mustBeDOM(tag, tp, attr)) {
if (hasDom && typeof context.domProps[attr] !== 'undefined') {
return;
}
context.domProps = context.domProps || {};
context.domProps[attr] = g(attr);
context.props && delete context.props[attr];
context.attrs && delete context.attrs[attr];
}
});
return context;
}