UNPKG

wux-weapp-utils-test

Version:
123 lines (102 loc) 3.13 kB
const isObject = (obj) => obj !== null && typeof obj === 'object' const getType = (fn) => { const match = fn && fn.toString().match(/^\s*function (\w+)/) return match ? match[1] : '' } const generateComponentTrace = (vm) => (`\n\nComponent is found in path "${vm.is}"${vm.id ? ' (element id of "' + vm.id + '")' : ''}.`) const warn = (msg, vm) => console.warn(`[Wux warn]: ${msg}${vm ? generateComponentTrace(vm) : ''}`) const simpleCheckRE = /^(String|Number|Boolean)$/ const assertType = (value, type) => { let valid const expectedType = getType(type) if (simpleCheckRE.test(expectedType)) { const t = typeof value valid = t === expectedType.toLowerCase() // for primitive wrapper objects if (!valid && t === 'object') { valid = value instanceof type } } else if (expectedType === 'Object') { valid = isPlainObject(value) } else if (expectedType === 'Array') { valid = Array.isArray(value) } else { valid = value instanceof type } return { valid, expectedType, } } const assertProp = (prop, name, value, vm) => { if (prop.required && value == null) { warn(`Missing required prop: "${name}".`, vm) return } // if (value == null && !prop.required) { // return // } let type = prop.type let valid = !type || type === true const expectedTypes = [] if (type) { if (!Array.isArray(type)) { type = [type] } for (let i = 0; i < type.length && !valid; i++) { const assertedType = assertType(value, type[i]) expectedTypes.push(assertedType.expectedType || '') valid = assertedType.valid } } // 判断类型是否一致 if (!valid) { warn(`Invalid prop: type check failed for prop "${name}". Expected ${expectedTypes.join(', ')}, got ${Object.prototype.toString.call(value).slice(8, -1)}.`, vm) return } // 判断自定义验证方法 if (prop.validator) { if (!prop.validator(value)) { warn(`Invalid prop: custom validator check failed for prop "${name}".`, vm) return } } } const baseComponent = (options = {}) => { const { properties, created } = options const props = {} if (properties && isObject(properties)) { for (let name in properties) { const value = properties[name] const prop = !isObject(value) ? { type: value } : value // const type = !Array.isArray(prop.type) ? prop.type : null const observer = typeof prop.observer === 'function' ? prop.observer : typeof prop.observer === 'string' ? options.methods[prop.observer] : null // 组件属性 props[name] = { type: null, value: prop.value, observer(...args) { assertProp(prop, name, args[0], this) if (observer) { observer.apply(this, args) } }, } } } /** * 组件生命周期函数,在组件实例进入页面节点树时执行 */ options.created = function () { for (let name in props) { assertProp(props[name], name, props[name].value, this) } if (created) { created.call(this) } } options.properties = props options.externalClasses = ['wux-class', ...(options.externalClasses = options.externalClasses || [])] return Component(options) } export default baseComponent