js 逻辑判断过程中,经常需要根据数值类型及内容进行逻辑判断处理,为简化处理逻辑, ES2020 引入空值合并运算符(??)、可选链操作符(?.)、空值赋值运算符(??=)等新特性。
一、前言
你可能在项目中写过这样的代码
const street = user.address && user.address.street;
有了这个js新语法,你可以写成
const street = user.address?.street;
但即使有新语法的加持,在实际使用中,还是会有些不便,比如
const result = response?.settings?.n || 100;
你希望如果 response 或者 response.settings 或者 response.settings.n 不存在(值为 null 或者 undefined)时,result 保底值为 100。
但是上面代码在 n 为 0 的时候,也会让 result 变成 100,你实际上希望此时 result 为 0。
于是你只好把代码写成这样
const result = response?.settings?.n === undefined ? 100 : response?.settings?.n;
幸运的是,现在你可以用另一个新语法——「空值合并运算符(??)」来简化代码
const result = response?.settings?.n ?? 100;
这个 ?? 的意思是,如果 ?? 左边的值是 null 或者 undefined,那么就返回右边的值。
还有 ??= 空赋值运算符,它表示仅在 x 是 null 或 undefined 时对其赋值,就像这样
let a = 0;
a ??= 1;
console.log(a); // 0
let b = null;
b ??= 1;
console.log(b); // 1
二、在vue2中如何使用
由于是新语法特性,浏览器支持还不完善,因此需要使用babel进行转化,下面介绍一下在vue项目中适合在js和template中使用可选链提升我们编码的可读性与效率。
1、安装依赖
npm install @babel/plugin-proposal-optional-chaining –save-dev
npm install @babel/plugin-proposal-nullish-coalescing-operator –save-dev
2、在babel.config.js中配置
module.exports = {
presets: [
'@vue/app',
],
plugins: [
'@babel/plugin-proposal-optional-chaining', //可选链 ?.
'@babel/plugin-proposal-nullish-coalescing-operator' //空值合并 ??
]
}
其他插件同样以上1和2的操作,常用插件
@babel/plugin-proposal-optional-chaining 可选链 ?.
@babel/plugin-proposal-nullish-coalescing-operator 空值合并运算符 ??
@babel/plugin-proposal-object-rest-spread 扩展运算符 ...
@babel/plugin-syntax-dynamic-import 顶层import
@babel/plugin-proposal-decorators 装饰器
3、在template中使用
目前Vue默认是不支持在template中使用可选链操作符的,如果我们想要实现可选链操作符类似的效果,可以自行实现,具体代码如下
utils.js
/**
* 解决Vue Template模板中无法使用可选链的问题
* @param obj
* @param rest
* @returns {*}
*/
export const optionalChaining = (obj, ...rest) => {
let tmp = obj;
for (let key in rest) {
let name = rest[key];
tmp = tmp?.[name];
}
return tmp || "";
};
main.js
import Vue from "vue";
import App from "./App.vue";
import {optionalChaining} from "./utils/index";
Vue.prototype.$$ = optionalChaining;
new Vue({
render: h => h(App)
}).$mount("#app");
template中使用
<template>
<div class="container">
<div class="username">{{$$(userInfo,"friends",0,"userName")}}</div>
</div>
</template>
<script>
export default {
name: "test",
data(){
return {
userInfo:{}
}
}
}
</script>
<style scoped>
</style>