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
}
vue.js 源代码学习笔记 ----- 工具方法 props的更多相关文章
- vue.js 源代码学习笔记 ----- 工具方法 env
/* @flow */ /* globals MutationObserver */ import { noop } from 'shared/util' // can we use __proto_ ...
- vue.js 源代码学习笔记 ----- 工具方法 option
/* @flow */ import Vue from '../instance/index' import config from '../config' import { warn } from ...
- vue.js 源代码学习笔记 ----- 工具方法 share
/* @flow */ /** * Convert a value to a string that is actually rendered. { .. } [ .. ] 2 => '' */ ...
- vue.js 源代码学习笔记 ----- 工具方法 lang
/* @flow */ // Object.freeze 使得这个对象不能增加属性, 修改属性, 这样就保证了这个对象在任何时候都是空的 export const emptyObject = Obje ...
- vue.js 源代码学习笔记 ----- 工具方法 perf
import { inBrowser } from './env' export let mark export let measure if (process.env.NODE_ENV !== 'p ...
- vue.js 源代码学习笔记 ----- 工具方法 error
import config from '../config' import { warn } from './debug' import { inBrowser } from './env' // 这 ...
- vue.js 源代码学习笔记 ----- 工具方法 debug
import config from '../config' import { noop } from 'shared/util' let warn = noop let tip = noop let ...
- vue.js 源代码学习笔记 ----- instance state
/* @flow */ import Dep from '../observer/dep' import Watcher from '../observer/watcher' import { set ...
- vue.js 源代码学习笔记 ----- observe
参考 vue 2.2.6版本 /* @flow */ //引入订阅者模式 import Dep from './dep' import { arrayMethods } from './array' ...
随机推荐
- webservice使用方法
1,右击项目选择-->添加服务引用: 填写一个 命名空间名称; 2, 实例化 命名空间名称 ; 选择 带client的服务名称进行初始化 3,开始调用方法 // 带参数的webservice ...
- mysql5.6备份
备份之前: 最初的二进制信息: mysql> show master logs; +------------------+-----------+ | Log_name | File_size ...
- 使用淘宝的npm代理下载模块
npm install node-sass --registry=http://registry.npm.taobao.org
- 【cs231n】反向传播笔记
前言 首先声明,以下内容绝大部分转自知乎智能单元,他们将官方学习笔记进行了很专业的翻译,在此我会直接copy他们翻译的笔记,有些地方会用红字写自己的笔记,本文只是作为自己的学习笔记.本文内容官网链接: ...
- ZJOI2017游记
$Day$ $-1$ 听说可以去$ZJOI2017$打酱油,终于可以出去走走辣$QAQ$... 上次出去打比赛似乎是$PKUSC$?? 好吧,至少可以一览国家预备队爷们的风采... 准备把膝盖留在浙江 ...
- 通过ajax提交到url路由
$regBoxform.find('button').on('click', function(){ /*通过ajax提交请求*/ $.ajax({ type:'post', /*用post 方式提交 ...
- SpringBoot学习(1)
内容概要: spring data springboot是spring团队基于spring4开发的一个框架. springboot来简化spring应用开发,约定大于配置,去繁从简,just run就 ...
- 以普通用户启动的Vim如何保存需要root权限的文件
在Linux上工作的朋友很可能遇到过这样一种情况,当你用Vim编辑完一个文件时,运行:wq保存退出,突然蹦出一个错误: E45: 'readonly' option is set (add ! to ...
- uva11626逆时针排序
给一个凸包,要求逆时针排序,刚开始一直因为极角排序就是逆时针的,所以一直wa,后来发现极角排序距离相同是,排的是随机的,所以要对末尾角度相同的点重新排一次 #include<map> #i ...
- java之JDBC多条语句执行
在开发过程中,有时我们需要执行多条SQL语句,那如何处理才能解决这样的问题? 1,多条语句执行错误 原因:试图用一个PreparedStatement对象,执行多次SQL操作.程序会提示一下错误: O ...