Props
template
const fooComponent = {
template: `<div>{{a}}</div>`,
props: ['a'],
}
const Foo = {
components: {
fooComponent,
},
template: `
<div>
<foo-component :a="a"></foo-component>
</div>
`
...
}
发生阶段
- 在
beforeCreate
阶段
vm.$options.propsData
和propsOptions
比较属性
- 上面这个
$options.propsData
从哪生成的呢?
function initProps(vm, propsOptions) {
const propsData = vm.$options.propsData || {}
const props = (vm._props = {})
const keys = (vm.$options._propKeys = [])
const isRoot = !vm.$parent
if (!isRoot) {
toggleObserving(false)
}
for (const key in propsOptions) {
keys.push(key)
const value = validateProp(key, propsOptions, propsData, vm)
{
const hyphenatedKey = hyphenate(key)
if (isReservedAttribute(hyphenatedKey) || config.isReservedAttr(hyphenatedKey)) {
warn(`"${hyphenatedKey}" is a reserved attribute and cannot be used as component prop.`, vm)
}
defineReactive$$1(props, key, value, () => {
if (!isRoot && !isUpdatingChildComponent) {
warn(
`Avoid mutating a prop directly since the value will be ` +
`overwritten whenever the parent component re-renders. ` +
`Instead, use a data or computed property based on the prop's ` +
`value. Prop being mutated: "${key}"`,
vm
)
}
})
}
if (!(key in vm)) {
proxy(vm, `_props`, key)
}
}
toggleObserving(true)
}
propsData
vnode = createComponent(Ctor, data, context, children, tag)
data = {
attrs: {
a: [1, 2]
}
}
const propsData = extractPropsFromVNodeData(data, Ctor, tag)
function extractPropsFromVNodeData(data, Ctor, tag) {
const propOptions = Ctor.options.props
if (isUndef(propOptions)) {
return
}
const res = {}
const { attrs, props } = data
if (isDef(attrs) || isDef(props)) {
for (const key in propOptions) {
const altKey = hyphenate(key)
{
const keyInLowerCase = key.toLowerCase()
if (key !== keyInLowerCase && attrs && hasOwn(attrs, keyInLowerCase)) {
tip(
`Prop "${keyInLowerCase}" is passed to component ` +
`${formatComponentName(tag || Ctor)}, but the declared prop name is` +
` "${key}". ` +
`Note that HTML attributes are case-insensitive and camelCased ` +
`props need to use their kebab-case equivalents when using in-DOM ` +
`templates. You should probably use "${altKey}" instead of "${key}".`
)
}
}
checkProp(res, props, key, altKey, true) || checkProp(res, attrs, key, altKey, false)
}
}
return res
}
function checkProp(res, hash, key, altKey, preserve) {
if (isDef(hash)) {
if (hasOwn(hash, key)) {
res[key] = hash[key]
if (!preserve) {
delete hash[key]
}
return true
} else if (hasOwn(hash, altKey)) {
res[key] = hash[altKey]
if (!preserve) {
delete hash[altKey]
}
return true
}
}
return false
}