Support optional chaining in vuejs Support optional chaining in vuejs vue.js vue.js

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>