Search code examples
vue.jsdatatablevuejs2vuetify.js

Vuetify v-data-table doesn't fully load data: blank rows


Vue version: 2.6.10

Vuetify version: 1.5

I am using example data of Vuetify 1.5.16 documentation: https://v15.vuetifyjs.com/en/components/data-tables

The table is shown correctly and I can edit appearance of it using props. The problem is that data is not fully loaded. There is exactly the same number of lines in table as there are objects in array but all lines are blank (blank td tags).

When I enabled prop "loading", it is all the time true (I can see progress line transition effect all the time).

{% extends 'base.html' %}
{% block title %}Page name{% endblock %}

{% block custom_style %}

<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">

<!-- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui"> -->
{% endblock %}


{% block content %} 
<v-app id="app-name">
        <template>
            <v-data-table dark loading no-data-text :headers="headers" :items="desserts"
                class="elevation-1">
                <template v-slot:items="props">
                    <td> {{ props.item.name }}</td>
                    <td class="text-xs-right">{{ props.item.calories }}</td>
                    <td class="text-xs-right">{{ props.item.fat }}</td>
                    <td class="text-xs-right">{{ props.item.carbs }}</td>
                    <td class="text-xs-right">{{ props.item.protein }}</td>
                    <td class="text-xs-right">{{ props.item.iron }}</td>
                </template>
            </v-data-table>
        </template>
    </div>
</v-app>
{% endblock %}
{% block custom_js_back %}


<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>


<script>

    var vueData = new Vue({
        delimiters: ["<%", "%>"],
        el: '#app-name',
        data: {
            // example data
            headers: [
                {
                    text: 'Dessert (100g serving)',
                    align: 'left',
                    sortable: false,
                    value: 'name',
                },
                { text: 'Calories', value: 'calories' },
                { text: 'Fat (g)', value: 'fat' },
                { text: 'Carbs (g)', value: 'carbs' },
                { text: 'Protein (g)', value: 'protein' },
                { text: 'Iron (%)', value: 'iron' },
            ],
            desserts: [
                {
                    name: 'Frozen Yogurt',
                    calories: 159,
                    fat: 6.0,
                    carbs: 24,
                    protein: 4.0,
                    iron: '1%',
                },
                {
                    name: 'Ice cream sandwich',
                    calories: 237,
                    fat: 9.0,
                    carbs: 37,
                    protein: 4.3,
                    iron: '1%',
                },
                {
                    name: 'Eclair',
                    calories: 262,
                    fat: 16.0,
                    carbs: 23,
                    protein: 6.0,
                    iron: '7%',
                },
            ],
        },
    });

</script>
{% endblock custom_js_back %}

Django probably has nothing to do with this.

The v-data-table component has all data but it is not shown in table


Solution

  • You are defining custom delimiters, so use them in place of the default ["{{", "}}"].

    Regarding the loading prop being all the time true, it's because when you do the following:

    <v-data-table loading>
    </v-data-table>
    

    without v-bind, you are actually setting the flag to true permanently (no data-binding). What you most likely want instead is to do v-bind:loading="loading" (or the shorter :loading="loading") where the similarly-named value (loading) is the property to bind the state to, in your data object.

    From here, you could toggle the state to true while fetching data (via axios or anything) to say "start loading", and so on and so forth.

    The same is true for the prop no-data-text -- if you don't need data-binding, you could simply put the custom text inline just as you would with any HTML attributes. e.g.

    <v-data-table no-data-text="No data to display">
    

    var vueData = new Vue({
      delimiters: ["<%", "%>"],
      el: '#app-name',
      data:() => ({
        // example data
        headers: [
          {
            text: 'Dessert (100g serving)',
            align: 'left',
            sortable: false,
            value: 'name'
          },
          { text: 'Calories', value: 'calories' },
          { text: 'Fat (g)', value: 'fat' },
          { text: 'Carbs (g)', value: 'carbs' },
          { text: 'Protein (g)', value: 'protein' },
          { text: 'Iron (%)', value: 'iron' }
        ],
        desserts: [
          {
            name: 'Frozen Yogurt',
            calories: 159,
            fat: 6.0,
            carbs: 24,
            protein: 4.0,
            iron: '1%',
          },
          {
            name: 'Ice cream sandwich',
            calories: 237,
            fat: 9.0,
            carbs: 37,
            protein: 4.3,
            iron: '1%',
          },
          {
            name: 'Eclair',
            calories: 262,
            fat: 16.0,
            carbs: 23,
            protein: 6.0,
            iron: '7%',
          }
        ],
        
        loading: false
      })
    });
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
    
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
    
    <div>
      <v-app id="app-name">
        <v-data-table
          :headers="headers"
          :items="desserts"
          :loading="loading"
          no-data-text="No data to display"
          dark
          class="elevation-1">
          <template v-slot:items="props">
            <td> <% props.item.name %></td>
            <td class="text-xs-right"><% props.item.calories %></td>
            <td class="text-xs-right"><% props.item.fat %></td>
            <td class="text-xs-right"><% props.item.carbs %></td>
            <td class="text-xs-right"><% props.item.protein %></td>
            <td class="text-xs-right"><% props.item.iron %></td>
          </template>
        </v-data-table>
      </v-app>
    </div>