zoukankan      html  css  js  c++  java
  • vue.js 源代码学习笔记 ----- 工具方法 props

    /* @flow */
    
    import { hasOwn, isObject, isPlainObject, capitalize, hyphenate } from 'shared/util'
    import { observe, observerState } from '../observer/index'
    import { warn } from './debug'
    
    type PropOptions = {
      type: Function | Array<Function> | null,
      default: any,
      required: ?boolean,
      validator: ?Function
    };
    
    export function validateProp (
      key: string,
      propOptions: Object,
      propsData: Object,
      vm?: Component
    ): any {
    const prop
    = propOptions[key]

    //如果 key不在 propsData中 const absent
    = !hasOwn(propsData, key)
    let value
    = propsData[key] // handle boolean props
    //如果 传入的属性是 bool类型
    if (isType(Boolean, prop.type)) { if (absent && !hasOwn(prop, 'default')) { value = false } else if (!isType(String, prop.type) && (value === '' || value === hyphenate(key))) { value = true } } // check default value if (value === undefined) { value = getPropDefaultValue(vm, prop, key) // since the default value is a fresh copy, // make sure to observe it. const prevShouldConvert = observerState.shouldConvert observerState.shouldConvert = true observe(value) observerState.shouldConvert = prevShouldConvert } if (process.env.NODE_ENV !== 'production') { assertProp(prop, key, value, vm, absent) } return value } /** * Get the default value of a prop. */ function getPropDefaultValue (vm: ?Component, prop: PropOptions, key: string): any { // no default, return undefined if (!hasOwn(prop, 'default')) { return undefined } const def = prop.default // warn against non-factory defaults for Object & Array if (process.env.NODE_ENV !== 'production' && isObject(def)) { warn( 'Invalid default value for prop "' + key + '": ' + 'Props with type Object/Array must use a factory function ' + 'to return the default value.', vm ) } // the raw prop value was also undefined from previous render, // return previous default value to avoid unnecessary watcher trigger if (vm && vm.$options.propsData && vm.$options.propsData[key] === undefined && vm._props[key] !== undefined) { return vm._props[key] } // call factory function for non-Function types // a value is Function if its prototype is function even across different execution context return typeof def === 'function' && getType(prop.type) !== 'Function' ? def.call(vm) : def } /** * Assert whether a prop is valid. */ function assertProp ( prop: PropOptions, name: string, value: any, vm: ?Component, absent: boolean ) { if (prop.required && absent) { 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.map(capitalize).join(', ') + ', got ' + Object.prototype.toString.call(value).slice(8, -1) + '.', vm ) return } const validator = prop.validator if (validator) { if (!validator(value)) { warn( 'Invalid prop: custom validator check failed for prop "' + name + '".', vm ) } } } /** * Assert the type of a value */ function assertType (value: any, type: Function): { valid: boolean, expectedType: ?string } { let valid let expectedType = getType(type) if (expectedType === 'String') { valid = typeof value === (expectedType = 'string') } else if (expectedType === 'Number') { valid = typeof value === (expectedType = 'number') } else if (expectedType === 'Boolean') { valid = typeof value === (expectedType = 'boolean') } else if (expectedType === 'Function') { valid = typeof value === (expectedType = 'function') } else if (expectedType === 'Object') { valid = isPlainObject(value) } else if (expectedType === 'Array') { valid = Array.isArray(value) } else { valid = value instanceof type } return { valid, expectedType } } /** * Use function string name to check built-in types, * because a simple equality check will fail when running * across different vms / iframes.

        Number.toString()
        "function Number() { [native code] }"

      Boolean.toString()
    "function Boolean() {[native code]}"

    toString 深入研究
    */ function getType (fn) { const match = fn && fn.toString().match(/^s*function (w+)/) return match && match[1] }
    //如果传入的是数组, 只要数组中有一个是type, 就判断为相等, 因为如果type: [Boolean, Fuction, Number] 说明这个组件的属性满足其中一个即可
    function isType (type, fn) { if (!Array.isArray(fn)) { return getType(fn) === getType(type) } for (let i = 0, len = fn.length; i < len; i++) { if (getType(fn[i]) === getType(type)) { return true } } /* istanbul ignore next */ return false }
  • 相关阅读:
    学习Android有感!
    使用PHP-Barcode轻松生成条形码(一)
    php利用redis实现分页列表,新增,删除功能
    JS验证input输入框(字母,数字,符号,中文)正则实现
    mac 安装swoole扩展
    git 配置本地SSH秘钥
    lnmp 一键安装
    lnmp php版本升级
    NATAPP内网穿透,本地进行微信开发,支付开发,对象存储回调信息
    微信公众号二维码
  • 原文地址:https://www.cnblogs.com/dhsz/p/7064954.html
Copyright © 2011-2022 走看看