首頁 >web前端 >Vue.js >一文帶你詳解Vue2 中的可選鍊式呼叫操作符'?.”

一文帶你詳解Vue2 中的可選鍊式呼叫操作符'?.”

青灯夜游
青灯夜游轉載
2022-02-14 20:34:086705瀏覽

這篇文章帶大家了解一下Vue2 中的可選鍊式呼叫操作符“?.”,聊聊 ?. 在 template中使用報錯的解決方法,希望對大家有所幫助!

一文帶你詳解Vue2 中的可選鍊式呼叫操作符'?.”

一、先說一下什麼是?.(可選鍊式呼叫運算子

#可選鏈運算子(  ?.  )允許讀取位於連接物件鏈深處的屬性的值,而不必明確驗證鏈中的每個引用是否有效。 ?. 運算子的功能類似 . 鍊式運算符,不同之處在於,在引用為空白(nullish ) (null 或 undefined) 的情況下不會造成錯誤,而此表達式短路回傳值為 undefined。與函數呼叫一起使用時,如果給定的函數不存在,則傳回 undefined。 【相關推薦:vue.js影片教學

連結: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/ Reference/Operators/Optional_chaining

簡單來說就是我們平常使用「。」運算元來取得物件某個值的一個升級版本。當上一個值不存在時防止undefined.東西報錯。
廢話不多說,直接上程式碼。

let obj = { a: { b: { c: ['冰墩墩', '冬奥会'] } } }

// 当我们想获取“冰墩墩”的时候
// 如果直接obj.a.b.c[0]的话a、b、c任意一项不存在的话都会报错

// 正确的做法是
obj && obj.a && obj.a.b && obj.a.b.c && obj.a.b.c[0] // 冰墩墩

// 而采用?.操作符的话 
obj?.a?.b?.c?.[0] // 冰墩墩

當我們工作中遇到嵌套無比深的資料結構時,用&&來校驗屬性是否存在。代碼就變的十分臃腫。可讀性和維護起來讓人頭皮發麻。但使用?. 就簡潔了不少,可閱讀性也大大提高

二、?. 在Vue2 template中使用問題

當我們學會一個新的技能興致勃勃想在代碼的世界中大露一手的時候,發現在Vue2環境下js中能正常使用?. ,但是在template中卻報錯。

一文帶你詳解Vue2 中的可選鍊式呼叫操作符?.”

Vue2 template中無法正常辨識?. 運算子可能是因為?. 可選鏈語法比較新,沒有在template中做關於這方面的處理

想必各位都不是等閒之輩,既然能在js中使用那我們就順著思路解決這個問題

三、解決方案

  • 第三方函式庫lodash中的_get 方法
  • 升級到vue3,目前vue3成為預設版本生態趨近成熟且template支援可選鏈運算子
  • computed計算屬性中使用?.
  • 對template原始碼進行攔截更改,程式碼侵入性過高
  • 寫一個hook掛到global/mixins上隨時呼叫

想了一圈只有最後一種方案最可靠說乾就乾,讓我們先來書寫一個自己的?. 函數

let obj = { a: { b: { c: ['冰墩墩', '冬奥会'] } } }

function variableJudge(obj, keyName, tag = '?.') {
  if (!obj) return undefined
  let keys = keyName.split(tag)
  return keys.reduce((objNew, keyItem) => {
    if (keyItem === '') return objNew
    if (keyItem.indexOf('.') !== -1) return variableJudge1(objNew, keyItem, '.')
    return objNew?.[keyItem]
  }, obj)
}
//------------------------------ Proxy 版本 --------------------------------------
function variableJudgeProxy(obj, tag = '?.') {
  if (!obj) return undefined
  return new Proxy(obj, {
    get: (obj, key) => {
      const keys = key.split(tag)
      return keys.reduce((objNew, keyItem) => {
        if (keyItem === '') return objNew
        if (keyItem.indexOf('.') !== -1) return variableJudgeProxy(objNew, '.')[keyItem]
        return objNew?.[keyItem]
      }, obj)
    }
  })
}
  console.log(variableJudge(obj, '?.a?.b?.c?.0')) //冰墩墩
  console.log(variableJudgeProxy(obj)['?.a?.b?.c?.0']) //冰墩墩

wait wait wait 既然我們要寫自己的 ?.函數為什麼要定義傳進來的keyName含有 ?. 呢。
為什麼不讓keyName直接是. 語法而且還擁有?. 的功能這樣既符合我們的開發習慣,又能達到我們的預期,豈不美哉
而且按理說如果上一個值是undefined的話我們應該直接reutrn,但是用reduce方法也無法提前中斷。
於是又優化了一版程式碼

let obj = { a: { b: { c: ['冰墩墩', '冬奥会'] } } }

const variableJudge = (obj, keyName) => {
  if (!obj) return null
  let keys = (keyName + '').split('.')
  let tempObj = obj
  for (let i = 0; i < keys.length; i++) {
    if (!tempObj) return
    if (keys[i] !== &#39;&#39;) tempObj = tempObj?.[keys[i]]
  }
  return tempObj
}
console.log(variableJudge(obj, &#39;.a.b.c.0&#39;)) //冰墩墩

然後我們掛到Vue原型上就可以隨時使用了

Vue.prototype.$vj = variableJudge

讓我們來看一下在template中如何使用

// 省去了臃肿的代码为空判断 是不是赏心悦目了
<div>{{ $vj(ugc, &#39;.itemList.item.pic.picList.1.picUrl&#39;) }}</div>

四、總結

#?.(可選鍊式呼叫運算子)其實還有很多的妙用等待大家的發掘,本文只為?. 在Vue2 中template中使用報錯的問題來圍繞展開

如果文章/ 代碼哪裡有可以優化的點歡迎大家提出
本文如果對你產生了幫助可以分享給其他人
既然都看到這裡了,創作不易,留下一個小小的讚吧。

更多程式相關知識,請造訪:程式設計影片! !

以上是一文帶你詳解Vue2 中的可選鍊式呼叫操作符'?.”的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除