Search code examples
vue.jsvue-component

Vue js: How to display list of components only when its required data is loaded from bakend?


I am new to Vue js. There are some tabs on a page; one is the Logs tab which shows the audit logs. I need to display a list of data on this tab, however, the data is loaded once the user clicks on the Logs tab. The problem is I don't know how to display this data when it is changed (downloaded from the backend)

There is a data auditLogs:[] and this is the code

<el-tabs v-model="currentTab" @tab-click="handleClick">
  <el-tab-pane :label="Data" name="question">...</el-tab-pane>             
  <el-tab-pane :label="Messages" name="messages">...</el-tab-pane>
  <el-tab-pane :label="Logs" name="audit-logs">
    <QuestionAuditLogComponent v-for="log in auditLogs"
        :audit-log="log"></QuestionAuditLogComponent>
  </el-tab-pane>
</el-tabs>

This is the method

handleClick(tab, event) {
  if(tab.name === 'audit-logs' && this.audioLogs.length === 0)
  {
      this.fetchAuditLogs();
  }
},
fetchAuditLogs()
{
  axios.get(route('api.questions.logs',
      {
        'model':'question',
        'model_id': this.$route.params.questionId
      }))
      .then((response) => {
        this.audioLogs = response.data.outcome.data;
      });
},

and this is QuestionAuditLogComponent component:

<template>
  <div>
    <h3>Elastic LogID : {{ auditLog.id }}</h3>
    <div class="row">
      <div class="col-md-3">Event: {{ auditLog.event }}</div>
      <div class="col-md-3">At: {{ auditLog.created_at }}</div>
      <div class="col-md-3">By: {{ auditLog.user_name }}</div>
      <div class="col-md-3">Question: {{ auditLog.auditable_id }}</div>
    </div>
  </div>
</template>

<script>
export default {
  name: "QuestionAuditLogComponent",
  props: {
    auditLog: Object,
  },
}
</script>

<style scoped>

</style>

Solution

  • you can just add condition to your component and it will show only when data.

    
    <el-tabs v-model="currentTab" @tab-click="handleClick">
      <el-tab-pane :label="Data" name="question">...</el-tab-pane>             
      <el-tab-pane :label="Messages" name="messages">...</el-tab-pane>
      <el-tab-pane :label="Logs" name="audit-logs" v-if="auditLogs.length>0">
        <QuestionAuditLogComponent v-for="log in auditLogs"
            :audit-log="log"></QuestionAuditLogComponent>
      </el-tab-pane>
    </el-tabs>
     
    

    Or you can add variable status what will change through axios request

    export default {
    ...
    data(){return {status:'empty',statusText:{load:'load'// and other
    }}
    },
    methods:{
    ...
    fetchAuditLogs()
    {
    this.status='load'
      axios.get(route('api.questions.logs',
          {
            'model':'question',
            'model_id': this.$route.params.questionId
          }))
          .then((response) => {
            this.audioLogs = response.data.outcome.data;
    this.status=this.audioLogs.length>0?"ok":"empty"
          }).catch(function (error) {this.status="error"});
    },
    ...
    },
    ...
    
    

    template

    
    <el-tabs v-model="currentTab" @tab-click="handleClick">
      <el-tab-pane :label="Data" name="question">...</el-tab-pane>             
      <el-tab-pane :label="Messages" name="messages">...</el-tab-pane>
      <el-tab-pane :label="Logs" name="audit-logs" >
        <QuestionAuditLogComponent v-for="log in auditLogs"
            :audit-log="log" v-if="status=='ok'"></QuestionAuditLogComponent>
        <div v-else>{{statusText[status]}} </div>
      </el-tab-pane>
    </el-tabs>