最近都在寫Vue相關的文章,感興趣的能夠看回我以前寫的。前端
props
初始化initProps
是如何運行的: vue
normalizeProps
: initProps
以前的規範化數據normalizeProps
的代碼有點長,這裏只列舉通過規範化後的prop
類型和結果vue-cli
props: ["data"]
// 規範化後
props: {
data:{
type: null
}
}
複製代碼
props: {
data1: {
type: String,
default: ''
}
data2: Number,
}
// 規範化後
props: {
data1: {
type: String,
default: ''
},
data2: {
type: Number
},
}
複製代碼
initProps
: 處理props
源碼分析以下:bash
function initProps (vm: Component, propsOptions: Object) {
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)
if (process.env.NODE_ENV !== 'production') {
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(props, key, value, () => {
if (!isRoot && !isUpdatingChildComponent) {
warn(
`Avoid mutating a prop direct....`,
vm
)
}
})
} else {
defineReactive(props, key, value)
}
if (!(key in vm)) {
proxy(vm, `_props`, key)
}
}
toggleObserving(true)
}
複製代碼
const propsData = vm.$options.propsData || {}
const props = vm._props = {}
const keys = vm.$options._propKeys = []
const isRoot = !vm.$parent
複製代碼
propsData
: 存儲着傳遞進來的 props
的值props: 引用
vm._props`,並初始化爲{}keys
: 在 vm.$options
上添加 _propKeys
屬性isRoot
: 判斷是否存在vm.$parent
,若無則爲根節點if (!isRoot) {
toggleObserving(false)
}
for (const key in propsOptions) {
// 省略...
}
toggleObserving(true)
複製代碼
!isRoot
:若當前實例非根節點,關閉toggleObserving
toggleObserving
: 能夠理解爲數據觀測的開關for...in
: 遍歷propsOptions
propsOptions
作什麼for (const key in propsOptions) {
keys.push(key)
const value = validateProp(key, propsOptions, propsData, vm)
if (process.env.NODE_ENV !== 'production') {
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(props, key, value, () => {
if (!isRoot && !isUpdatingChildComponent) {
warn(
`Avoid mutating a prop directly since the value will be ` +
`overwri tten whenever the parent component re-renders. ` +
`Instead, use a data or computed property based on the prop's ` + `value. Prop being mutated: "${key}"`, vm ) } }) } else { defineReactive(props, key, value) } } 複製代碼
劃重點:微信
propsOptions
即opts.props
key
就是每一個 prop
的名字此時進入循環:函數
keys.push(key)
const value = validateProp(key, propsOptions, propsData, vm)
複製代碼
key
添加到 vm.$options._propKeys
value
: 用validateProp
校驗是否爲預期的類型值,而後返回相應 prop 值(或default值)if...else
:這裏註釋一下:工具
if (process.env.NODE_ENV !== 'production') {
// 駝峯轉連字符
const hyphenatedKey = hyphenate(key)
// 校驗prop是否爲內置的屬性
// 內置屬性:key,ref,slot,slot-scope,is
if (isReservedAttribute(hyphenatedKey) ||
config.isReservedAttr(hyphenatedKey)) {
warn(
`"${hyphenatedKey}" is a reserved attribute and cannot be used as component prop.`,
vm
)
}
defineReactive(props, key, value, () => {
// 子組件直接修改屬性時 彈出警告
if (!isRoot && !isUpdatingChildComponent) {
warn(
`Avoid mutating a prop directly since the value will be ` +
`overwri tten whenever the parent component re-renders. ` +
`Instead, use a data or computed property based on the prop's ` + `value. Prop being mutated: "${key}"`, vm ) } }) } else { defineReactive(props, key, value) } 複製代碼
最後簡化:源碼分析
if (process.env.NODE_ENV !== 'production') {
// 駝峯轉連字符
// 校驗prop是否爲內置的屬性
// 內置屬性:key,ref,slot,slot-scope,is
// 如果內置,彈出警告
defineReactive(props, key, value, () => {
// 子組件直接修改屬性時 彈出警告
} else {
defineReactive(props, key, value)
}
複製代碼
工具函數: 「從源碼中學習」Vue源碼中的JS騷操做post
defineReactive
: 最終處理defineReactive(props, key, value)
複製代碼
defineReactive
是老熟人了,但這裏要注意一點: 先前toggleObserving(false)
,關閉了觀測的開關,因此defineReactive
中調用 observe
, 是一個無效調用。學習
此時到這裏,能夠得出一個結論
props
是經過 defineReactive
定義的,此時雖然是響應式數據,但沒有進行深度定義。
即,父組件傳給子組件props後,子組件沒必要再重複觀測props
toggleObserving(true)
複製代碼
從新打開觀測開關,避免影響後續代碼執行。
目前本人在準備跳槽,但願各位大佬和HR小姐姐能夠內推一份靠譜的深圳前端崗位!
huab119
454274033@qq.com