Support optional chaining in vuejs
One quick update is that Vue 3 comes bundled with support for optional chaining.
To test you can try compiling the below Vue component code.
<template> <div id="app" v-if="user?.username"> @{{ user?.username }} - {{ fullName }} <strong>Followers: </strong> {{ followers }} <button style="align-self: center" @click="followUser">Follow</button> </div></template><script lang="ts">import { defineComponent } from 'vue'export default defineComponent({ name: 'App', props: { test: Object }, data() { return { followers: 0, user: { id: 1, test: {}, username: '_sethAkash', firstName: undefined, lastName: 'Seth', email: 'sethakash007@gmail.com', isAdmin: true } } }, computed: { fullName(): string { // return `${this?.test?.firstName} ${this?.user?.lastName}` } }, methods: { followUser: function () { this.followers += 1 } }, watch: { followers(newFollowerCount, oldFollowerCount) { if (oldFollowerCount < newFollowerCount) { console.log(`${this?.user?.username} has gained a follower!`) } } }, mounted() { this.followUser() }})</script>
According to this comment on an issue here
You could create a global mixin and use the eval
function to evaluate the expression.
Example:
Vue.mixin({ methods: { $evaluate: param => eval('this.'+param) }});
In the template:
<template> <p>{{ $evaluate('user?.name') }}</p></template>
They also added that it might not be perfect:
Although it's still no substitute for the real operator, especially if you have many occurrences of it
Edit
As stated above, using eval
may bring some unintended problems, I suggest you use a computed property instead.
In the SFC:
<template> <p>{{ userName }}</p></template><script>export default { data(){ return { user: { firstName: 'Bran' } } }, computed: { userName(){ return this.user?.firstName } }}</script>
After search many possibilities, I maked one function to help me.
Make one js file to save the helper function and export it
const propCheck = function (obj = {}, properties = ""){ const levels = properties.split("."); let objProperty = Object.assign({}, obj); for ( let level of levels){ objProperty = objProperty[level]; if(!objProperty) return false; } return true;}export default propCheck;
And install this function for globally in the Vue instance
Vue.prototype.$propCheck = propCheck;
After use in your template
<span>{{$propCheck(person, "name")}}</span>
or
<span>{{$propCheck(person, "contatcs.0.address")}}</span>
or
<span>{{$propCheck(person, "addres.street")}}</span>