Vue2 的可选链式调用操作符“?.”
一、先说一下什么是?.(可选链式调用操作符)
链接: 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 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] !== '') tempObj = tempObj?.[keys[i]]
}
return tempObj
}
console.log(variableJudge(obj, '.a.b.c.0')) //冰墩墩
然后我们挂到Vue原型上就可以随时使用了
Vue.prototype.$vj = variableJudge
让我们来看一下在template中如何使用
// 省去了臃肿的代码为空判断 是不是赏心悦目了
<div>{{ $vj(ugc, '.itemList.item.pic.picList.1.picUrl') }}</div>
四、总结
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tangbhgeb
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24