Vue?mergeProps用法詳細(xì)講解
很多人不知道m(xù)egreProps的用法,今天我們就來(lái)講解下mergeProps的用法以及原理
用法
大家覺(jué)得下面哪種用法是正確的呢?
這樣
style: mergeProps({
width: this.itemWidth
}, xProps.style)
或者這樣
style: mergeProps({
style: {
width: this.itemWidth
},
...(xProps?.style ?? {})
})
還是這樣
style: mergeProps(
{
style: { width: this.itemWidth },
},
xProps,
).style
你使用的話會(huì)使用上面哪一種呢?
不知道
因?yàn)閷?xiě)的是jsx語(yǔ)法,所以查看了vue3的jsx語(yǔ)法,發(fā)現(xiàn)里面并沒(méi)有關(guān)于這個(gè)解釋,只說(shuō)到了默認(rèn)開(kāi)啟
于是去vue3官網(wǎng)查找,找到
megreProps:Merge multiple props objects with special handling for certain props.
意思就說(shuō)合并多個(gè)道具對(duì)象,對(duì)某些道具進(jìn)行特殊處理
所以前面兩種寫(xiě)法是錯(cuò)誤的
接著看了下mergeProps源碼的寫(xiě)法
// ...args將多個(gè)對(duì)象收集成數(shù)組
export function mergeProps(...args: (Data & VNodeProps)[]) {
// 最終合并的結(jié)果
const ret: Data = {}
// 遍歷用戶傳入的多個(gè)對(duì)象
for (let i = 0; i < args.length; i++) {
// 取到傳入的對(duì)象值
const toMerge = args[i]
for (const key in toMerge) {
// 對(duì)class進(jìn)行序列化合并處理
if (key === 'class') {
if (ret.class !== toMerge.class) {
ret.class = normalizeClass([ret.class, toMerge.class])
}
// 對(duì)style進(jìn)行序列化合并處理
} else if (key === 'style') {
ret.style = normalizeStyle([ret.style, toMerge.style])
// 對(duì)其他的綁定的屬性進(jìn)行合并
} else if (isOn(key)) {
const existing = ret[key]
const incoming = toMerge[key]
if (
incoming &&
existing !== incoming &&
!(isArray(existing) && existing.includes(incoming))
) {
ret[key] = existing
? [].concat(existing as any, incoming as any)
: incoming
}
// 如果是普通元素上的用戶自定義屬性,則直接賦值
} else if (key !== '') {
ret[key] = toMerge[key]
}
}
}
return ret
}
所以你傳入的對(duì)象里面是需要有style、class等key的
接下來(lái)看看normalizeClass這個(gè)方法,這個(gè)方法就是將用戶寫(xiě)的多種格式(比如數(shù)組,對(duì)象,字符串)的class進(jìn)行序列化成字符串給到最終渲染的元素
export function normalizeClass(value: unknown): string {
let res = ''
// 如果是字符串,直接返回
if (isString(value)) {
res = value
// 如果是數(shù)組
} else if (isArray(value)) {
for (let i = 0; i < value.length; i++) {
// 遞歸調(diào)用進(jìn)行處理
const normalized = normalizeClass(value[i])
if (normalized) {
res += normalized + ' '
}
}
// 如果是對(duì)象, 如{ active: isActive, 'text-danger': hasError },需要把key拼接
} else if (isObject(value)) {
for (const name in value) {
if (value[name]) {
res += name + ' '
}
}
}
return res.trim()
}
再看看normalizeStyle這個(gè)函數(shù)
export type NormalizedStyle = Record<string, string | number>
export function normalizeStyle(
value: unknown
): NormalizedStyle | string | undefined {
// 如果是數(shù)組的情況
if (isArray(value)) {
const res: NormalizedStyle = {}
for (let i = 0; i < value.length; i++) {
const item = value[i]
const normalized = isString(item)
? parseStringStyle(item)
: (normalizeStyle(item) as NormalizedStyle)
if (normalized) {
// 將序列化后的style保存到ret上
for (const key in normalized) {
res[key] = normalized[key]
}
}
}
return res
} else if (isString(value)) {
return value
} else if (isObject(value)) {
return value
}
}
parseStringStyle函數(shù)就是將字符串對(duì);進(jìn)行分割,然后設(shè)置對(duì)應(yīng)的key,value
元素上的style只能使用string,所以在最終掛在到dom元素上需要進(jìn)行stringifyStyle
export function stringifyStyle(
styles: NormalizedStyle | string | undefined
): string {
let ret = ''
if (!styles || isString(styles)) {
return ret
}
for (const key in styles) {
const value = styles[key]
const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key)
if (
isString(value) ||
(typeof value === 'number' && isNoUnitNumericStyleProp(normalizedKey))
) {
// only render valid values
ret += `${normalizedKey}:${value};`
}
}
return ret
}
所以通過(guò)簡(jiǎn)單的對(duì)vue3的mergeProps的代碼進(jìn)行簡(jiǎn)單分析就能知道其原理了,使用上也會(huì)更加的熟練
到此這篇關(guān)于Vue mergeProps用法詳細(xì)講解的文章就介紹到這了,更多相關(guān)Vue mergeProps內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3+element?Plus實(shí)現(xiàn)表格前端分頁(yè)完整示例
這篇文章主要給大家介紹了關(guān)于vue3+element?Plus實(shí)現(xiàn)表格前端分頁(yè)的相關(guān)資料,雖然很多時(shí)候后端會(huì)把分頁(yè),搜索,排序都做好,但是有些返回?cái)?shù)據(jù)并不多的頁(yè)面,或者其他原因不能后端分頁(yè)的通常會(huì)前端處理,需要的朋友可以參考下2023-08-08
解決$store.getters調(diào)用不執(zhí)行的問(wèn)題
今天小編就為大家分享一篇解決$store.getters調(diào)用不執(zhí)行的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11
vue.js如何在網(wǎng)頁(yè)中實(shí)現(xiàn)一個(gè)金屬拋光質(zhì)感的按鈕
這篇文章主要給大家介紹了關(guān)于vue.js如何在網(wǎng)頁(yè)中實(shí)現(xiàn)一個(gè)金屬拋光質(zhì)感的按鈕的相關(guān)資料,文中給出了詳細(xì)的實(shí)例代碼以及圖文將實(shí)現(xiàn)的方法介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04
Nginx配置Vue項(xiàng)目,無(wú)法按路徑跳轉(zhuǎn)及刷新404的解決方案
這篇文章主要介紹了Nginx配置Vue項(xiàng)目,無(wú)法按路徑跳轉(zhuǎn)及刷新404的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
Vue-Router進(jìn)階之滾動(dòng)行為詳解
本篇文章主要介紹了Vue-Router進(jìn)階之滾動(dòng)行為詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09
詳解Vue如何在頁(yè)面刷新時(shí)進(jìn)行重定向
這篇文章主要為大家詳細(xì)介紹了Vue如何在頁(yè)面刷新時(shí)進(jìn)行重定向,文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下2025-01-01

