fix: get options props

pull/2415/head^2
tanjinzhou 2020-06-12 18:27:07 +08:00
parent 41129be9b6
commit f4c1c4569d
2 changed files with 61 additions and 14 deletions

View File

@ -1,14 +1,12 @@
import isPlainObject from 'lodash/isPlainObject';
import classNames from 'classnames';
import { isVNode } from 'vue';
import { camelize, hyphenate, isOn, resolvePropValue } from './util';
// function getType(fn) {
// const match = fn && fn.toString().match(/^\s*function (\w+)/);
// return match ? match[1] : '';
// }
const onRE = /^on[^a-z]/;
export const isOn = key => onRE.test(key);
const splitAttrs = attrs => {
const allAttrs = Object.keys(attrs);
const eventAttrs = {};
@ -25,10 +23,6 @@ const splitAttrs = attrs => {
}
return { onEvents, events: eventAttrs, extraAttrs };
};
const camelizeRE = /-(\w)/g;
const camelize = str => {
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
};
const parseStyleText = (cssText = '', camel) => {
const res = {};
const listDelimiter = /;(?![^(]*\))/g;
@ -101,17 +95,19 @@ const getOptionProps = instance => {
const props = instance.$.vnode.props || {};
Object.keys(instance.$props).forEach(k => {
const v = instance.$props[k];
if (v !== undefined || k in props) {
res[k] = k in props ? props[k] : v;
const hyphenateKey = hyphenate(k);
if (v !== undefined || hyphenateKey in props) {
res[k] = v; // 直接取 $props[k]
}
});
} else if (isVNode(instance) && typeof instance.type === 'object') {
const props = instance.props || {};
const allProps = instance.type.props;
Object.keys(allProps).forEach(k => {
const v = allProps[k].default;
if (v !== undefined || k in props) {
res[k] = k in props ? props[k] : v;
const options = instance.type.props;
Object.keys(options).forEach(k => {
const hyphenateKey = hyphenate(k);
const v = resolvePropValue(options, props, k, props[hyphenateKey], hyphenateKey);
if (v !== undefined || hyphenateKey in props) {
res[k] = v;
}
});
}

51
components/_util/util.js Normal file
View File

@ -0,0 +1,51 @@
const isFunction = val => typeof val === 'function';
const onRE = /^on[^a-z]/;
const isOn = key => onRE.test(key);
const cacheStringFunction = fn => {
const cache = Object.create(null);
return str => {
const hit = cache[str];
return hit || (cache[str] = fn(str));
};
};
const camelizeRE = /-(\w)/g;
const camelize = cacheStringFunction(str => {
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
});
const hyphenateRE = /\B([A-Z])/g;
const hyphenate = cacheStringFunction(str => {
return str.replace(hyphenateRE, '-$1').toLowerCase();
});
const capitalize = cacheStringFunction(str => {
return str.charAt(0).toUpperCase() + str.slice(1);
});
const hasOwnProperty = Object.prototype.hasOwnProperty;
const hasOwn = (val, key) => hasOwnProperty.call(val, key);
// change from vue sourcecode
function resolvePropValue(options, props, key, value, hyphenateKey) {
const opt = options[key];
if (opt != null) {
const hasDefault = hasOwn(opt, 'default');
// default values
if (hasDefault && value === undefined) {
const defaultValue = opt.default;
value = opt.type !== Function && isFunction(defaultValue) ? defaultValue() : defaultValue;
}
// boolean casting
if (opt[0 /* shouldCast */]) {
if (!hasOwn(props, hyphenateKey) && !hasDefault) {
value = false;
} else if (opt[1 /* shouldCastTrue */] && (value === '' || value === hyphenateKey)) {
value = true;
}
}
}
return value;
}
export { isOn, cacheStringFunction, camelize, hyphenate, capitalize, resolvePropValue };