最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

從vue源碼看props的用法

 更新時(shí)間:2019年01月09日 08:12:21   作者:你假裝沒(méi)察覺(jué)  
平時(shí)寫(xiě)vue的時(shí)候知道 props 有很多種用法,今天我們來(lái)看看vue內(nèi)部是怎么處理 props 中那么多的用法的。非常具有實(shí)用價(jià)值,需要的朋友可以參考下

前言

平時(shí)寫(xiě)vue的時(shí)候知道 props 有很多種用法,今天我們來(lái)看看vue內(nèi)部是怎么處理 props 中那么多的用法的。

vue提供的props的用法

1. 數(shù)組形式

props: ['name', 'value']

2. 對(duì)象形式

對(duì)象形式內(nèi)部也提供了三種寫(xiě)法:

props: {
 // 基礎(chǔ)的類(lèi)型檢查
 name: String,
 // 多個(gè)可能的類(lèi)型
 value: [String, Number],
 // 對(duì)象形式
 id: {
  type: Number,
  required: true
 }
}

props實(shí)現(xiàn)的原理

function normalizeProps (options: Object, vm: ?Component) {
 const props = options.props
 if (!props) return
 const res = {}
 let i, val, name
 if (Array.isArray(props)) {
 ...
 } else if (isPlainObject(props)) {
 ...
 } else if (process.env.NODE_ENV !== 'production') {
 ...
 }
 options.props = res
}

normalizeProps 函數(shù)就是vue實(shí)際處理 props 的地方,從函數(shù)名的翻譯我們可以看出該函數(shù)的功能就是標(biāo)準(zhǔn)化 props 的值。該函數(shù)主要分成3部分:① 從 options 對(duì)象中獲取 props 的值并且定義一個(gè)res空對(duì)象;②幾個(gè) if ... else ,分別根據(jù) props 值的不同類(lèi)型來(lái)處理 res 對(duì)象;③ 用處理后的 res 對(duì)象覆蓋原來(lái) options 對(duì)象的 props 屬性的值。

接下來(lái)看看那幾個(gè) if ... else 的代碼:

if (Array.isArray(props)) {
 i = props.length
 while (i--) {
  val = props[i]
  if (typeof val === 'string') {
  name = camelize(val)
  res[name] = { type: null }
  } else if (process.env.NODE_ENV !== 'production') {
  warn('props must be strings when using array syntax.')
  }
 }
 }

這個(gè)代碼實(shí)際就是處理props的值為數(shù)組的情況,例如: props: ['name', 'value'] 。使用while遍歷該數(shù)組,如果數(shù)組內(nèi)元素的類(lèi)型不是字符串并且不是生產(chǎn)環(huán)境,那么就拋錯(cuò):‘props的值類(lèi)型為數(shù)組時(shí),數(shù)組里面的元素的類(lèi)型就必須是字符串'。如果是字符串的情況下,使用 camelize 函數(shù)處理一下 val 的值,并且賦值給 name 變量。這里的 camelize 函數(shù)的實(shí)際作用就是將 '-' 轉(zhuǎn)換為駝峰。 camelize 函數(shù)具體的實(shí)現(xiàn)方式在后面分析。然后在 res 對(duì)象上面添加一個(gè)為 name 變量的屬性,該屬性的值為空對(duì)象 { type: null } 。

props: ['name', 'value'] 這種寫(xiě)法經(jīng)過(guò)上面的處理后就會(huì)變成了下面這樣:

props: {
 name: {
  type: null
 },
 value: {
  type: null
 }
}

接下來(lái)看看下面這個(gè) else if(isPlainObject(props)) ,這里的 isPlainObject 函數(shù)實(shí)際就是返回 props 的值是否為 object , isPlainObject 函數(shù)的具體實(shí)現(xiàn)我們也在后面分析。

else if (isPlainObject(props)) {
 for (const key in props) {
  val = props[key]
  name = camelize(key)
  res[name] = isPlainObject(val)
  ? val
  : { type: val }
 }
 }

使用 for...in 遍歷props對(duì)象,和上面一樣使用 camelize 函數(shù)將 '-' 轉(zhuǎn)換為駝峰。這里有個(gè)三目運(yùn)算:

res[name] = isPlainObject(val) ? val : { type: val }

判斷了一下 val 如果是 object ,那么在res對(duì)象上面添加一個(gè)為name變量的屬性,并且將該屬性的值設(shè)置為val。這個(gè)其實(shí)就是處理下面這種props的寫(xiě)法:

props: {
 // 對(duì)象形式
 id: {
  type: Number,
  required: true
 }
}

如果 val 不是 object ,那么也在res對(duì)象上面添加一個(gè)為name變量的屬性,并且將該屬性的值設(shè)置為{ type: val }。這個(gè)其實(shí)就是處理下面這種props的寫(xiě)法:

props: {
 // 基礎(chǔ)的類(lèi)型檢查
 name: String,
 // 多個(gè)可能的類(lèi)型
 value: [String, Number],
}

經(jīng)過(guò)處理后props會(huì)變成了下面這樣:

props: {
 name: {
  type: String
 },
 value: {
  type: [String, Number]
 }
}

所以不管我們使用vue提供的 props 哪種寫(xiě)法,最終vue都會(huì)幫我們轉(zhuǎn)換成下面這種類(lèi)型:

props: {
 name: {
  ...,
  type: '類(lèi)型'
 }
}

接下來(lái)看看上面提到的util函數(shù) isPlainObject ,先把源碼貼出來(lái)。

const _toString = Object.prototype.toString

export function isPlainObject (obj: any): boolean {
 return _toString.call(obj) === '[object Object]'
}

其實(shí) Object.prototype.toString.call(obj) 的值為obj對(duì)象的類(lèi)型。例如:

Object.prototype.toString.call({a: 1})  // [object Object]
Object.prototype.toString.call(new Date) // [object Date]
Object.prototype.toString.call([1])   // [object Array]
Object.prototype.toString.call(null)  // [object Null]

接下來(lái)看看上面提到的util函數(shù) camelize ,還是先把源碼貼出來(lái)。

export function cached<F: Function> (fn: F): F {
 const cache = Object.create(null)
 return (function cachedFn (str: string) {
 const hit = cache[str]
 return hit || (cache[str] = fn(str))
 }: any)
}

const camelizeRE = /-(\w)/g
export const camelize = cached((str: string): string => {
 return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})

這里定義了兩個(gè)函數(shù),分別是 cached 和 camelize ,其中 camelize 就是我們上面調(diào)用的, cached 是在 camelize 函數(shù)內(nèi)部調(diào)用的。

我們先來(lái)看看 camelize 函數(shù),其實(shí) camelize 函數(shù)就是執(zhí)行 cached 后返回的一個(gè)函數(shù)。調(diào)用 cached 時(shí)傳入了一個(gè)箭頭函數(shù),箭頭函數(shù)內(nèi)部是調(diào)用了正則的 replace 方法,將傳入的 str 變量中匹配 /-(\w)/g 的變成大寫(xiě)字母,并且返回 replace 后的值。(也就是將 - 轉(zhuǎn)換成駝峰)。

再來(lái)看看 cached 函數(shù),該函數(shù)傳入的變量其實(shí)就是 camelize 那里的箭頭函數(shù),首先定義了一個(gè) cache 空對(duì)象,然后直接返回了 cachedFn 函數(shù)。我們?cè)谕獠空{(diào)用 camelize(key) 時(shí),其實(shí)就是執(zhí)行了這里的了 cachedFn 函數(shù), str 的值就是傳入的 key 的值。很明顯這里是一個(gè)閉包,可以在外部調(diào)用 camelize 函數(shù)的時(shí)候可以修改或者讀取這里定義的 cache 對(duì)象的值。獲取 cache 對(duì)象中 key 為 str 變量值的屬性值賦值給 hit 變量。如果有hit變量的值,那么就直接返回hit的值,如果沒(méi)有就執(zhí)行 camelize 傳入的箭頭函數(shù),并且將箭頭函數(shù)的返回值賦值給 catche 對(duì)象的 str 屬性。如果下次調(diào)用 camelize 函數(shù)時(shí)傳入了相同的 str ,那么就不會(huì)執(zhí)行箭頭函數(shù),直接返回閉包中的 cache 對(duì)象的 str 屬性的值。這里是性能優(yōu)化的一種手段。

例如:第一次調(diào)用 camelize('name') 后, cache 對(duì)象的值就變成了{(lán)name: 'name'}。然后在其他地方再次調(diào)用 camelize('name') 時(shí)再次執(zhí)行 cachedFn 函數(shù),此時(shí) hit 變量的值為'name'。直接返回 hit 變量的值,不會(huì)執(zhí)行傳入的箭頭函數(shù)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue兩個(gè)同級(jí)組件傳值實(shí)現(xiàn)

    Vue兩個(gè)同級(jí)組件傳值實(shí)現(xiàn)

    Vue組件之間是有聯(lián)系的,避免不了組件之間要互相傳值,那么如何實(shí)現(xiàn)Vue兩個(gè)同級(jí)組件傳值,本文就來(lái)介紹一下,感興趣的可以了解一下
    2021-07-07
  • vue.js中導(dǎo)出Excel表格的案例分析

    vue.js中導(dǎo)出Excel表格的案例分析

    這篇文章主要介紹了vue.js中如何導(dǎo)出Excel表格,在項(xiàng)目中經(jīng)常會(huì)遇到這樣的需求,今天小編分步驟通過(guò)實(shí)例代碼給大家詳細(xì)介紹,需要的朋友可以參考下
    2019-06-06
  • vue項(xiàng)目首屏加載過(guò)慢的一些解決方案

    vue項(xiàng)目首屏加載過(guò)慢的一些解決方案

    最近碰到vue項(xiàng)目打包上線(xiàn)后,第一次打開(kāi)首頁(yè)后會(huì)出現(xiàn)空白、加載時(shí)間過(guò)長(zhǎng)的情況,下面這篇文章主要給大家介紹了關(guān)于vue項(xiàng)目首屏加載過(guò)慢的一些解決方案,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Vue使用codemirror實(shí)現(xiàn)一個(gè)可插入自定義標(biāo)簽的textarea

    Vue使用codemirror實(shí)現(xiàn)一個(gè)可插入自定義標(biāo)簽的textarea

    這篇文章主要為大家詳細(xì)介紹了Vue如何使用codemirror實(shí)現(xiàn)一個(gè)可插入自定義標(biāo)簽的textarea,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • Vue報(bào)錯(cuò)Component?name"Home"should?always?be?multi問(wèn)題

    Vue報(bào)錯(cuò)Component?name"Home"should?always?be?mult

    這篇文章主要介紹了Vue報(bào)錯(cuò)Component?name"Home"should?always?be?multi問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 關(guān)于uniapp的高級(jí)表單組件mosowe-form

    關(guān)于uniapp的高級(jí)表單組件mosowe-form

    這篇文章主要介紹了關(guān)于uniapp的高級(jí)表單組件mosowe-form,由于一些表單標(biāo)簽改來(lái)改去比較繁瑣,重復(fù)性很多,且樣式布局啥的幾乎萬(wàn)變不離其中,為了偷懶,開(kāi)發(fā)了mosowe-form及mosowe-table兩款高級(jí)組件,需要的朋友可以參考下
    2023-04-04
  • 深入理解Vue3響應(yīng)式原理

    深入理解Vue3響應(yīng)式原理

    響應(yīng)式就是當(dāng)對(duì)象本身(對(duì)象的增刪值)或者對(duì)象屬性(重新賦值)發(fā)生變化時(shí),將會(huì)運(yùn)行一些函數(shù),最常見(jiàn)的就是render函數(shù),下面這篇文章主要給大家介紹了關(guān)于Vue3響應(yīng)式原理的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • vue2自定義組件通過(guò)rollup配置發(fā)布到npm的詳細(xì)步驟

    vue2自定義組件通過(guò)rollup配置發(fā)布到npm的詳細(xì)步驟

    這篇文章主要介紹了vue2自定義組件通過(guò)rollup配置發(fā)布到npm,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Vue表單驗(yàn)證?trigger:'blur'OR?trigger:'change'區(qū)別解析

    Vue表單驗(yàn)證?trigger:'blur'OR?trigger:'change&ap

    利用?elementUI?實(shí)現(xiàn)表單元素校驗(yàn)時(shí),出現(xiàn)下拉框內(nèi)容選中后校驗(yàn)不消失的異常校驗(yàn)情形,這篇文章主要介紹了Vue表單驗(yàn)證?trigger:‘blur‘?OR?trigger:‘change‘?區(qū)別,需要的朋友可以參考下
    2023-09-09
  • Vue完整版和runtime版的區(qū)別詳解

    Vue完整版和runtime版的區(qū)別詳解

    這篇文章主要為大家介紹了Vue完整版和runtime版的區(qū)別詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12

最新評(píng)論

剑阁县| 措勤县| 明溪县| 永新县| 揭东县| 仁怀市| 旬邑县| 绿春县| 安陆市| 红原县| 麻城市| 秦安县| 景德镇市| 邛崃市| 清苑县| 江安县| 武山县| 奇台县| 瑞丽市| 望江县| 页游| 全州县| 偏关县| 呼伦贝尔市| 长海县| 屏东县| 益阳市| 通江县| 漳州市| 吉林省| 华安县| 章丘市| 玛纳斯县| 张家口市| 碌曲县| 蕉岭县| 徐汇区| 邯郸县| 班玛县| 恩施市| 普安县|