简体   繁体   English

使用 vue js 隐藏表格列

[英]Hide table column with vue js

Hello i need to hide or show columns of my datatable, I do not know what the good practice to do this, When columns checkboxes is checked the columns will shown and if it's not checked the column will be hidden?你好我需要隐藏或显示我的DataTable的列,我不知道这样做的好的做法,当检查列复选框时,将显示列,如果它没有检查,则将隐藏列? I'm using vuetify https://codepen.io/anon/pen/rmXwYG?editors=1010我正在使用 vuetify https://codepen.io/anon/pen/rmXwYG?editors=1010

This my script :这是我的脚本:

new Vue({
    el: '#app',
    data() {
      return {
        search: '',
        totalItems: 0,
        items: [],
        loading: true,
        pagination: {},
        columns: [],
        headers: [{
                text: 'Dessert (100g serving)',
                left: true,
                sortable: false,
                value: 'name'
            },
            {
                text: 'Calories',
                value: 'calories'
            },
            {
                text: 'Fat (g)',
                value: 'fat'
            },
            {
                text: 'Carbs (g)',
                value: 'carbs'
            },
            {
                text: 'Protein (g)',
                value: 'protein'
            },
            {
                text: 'Sodium (mg)',
                value: 'sodium'
            },
            {
                text: 'Calcium (%)',
                value: 'calcium'
            },
            {
                text: 'Iron (%)',
                value: 'iron'
            }
        ]
    }
    },
    watch: {
        pagination: {
            handler() {
                this.getDataFromApi()
                    .then(data => {
                        this.items = data.items
                        this.totalItems = data.total
                    })
            },
            deep: true
        }
    },
    mounted() {
        this.getDataFromApi()
            .then(data => {
                this.items = data.items
                this.totalItems = data.total
            })
    },
    methods: {
        getDataFromApi() {
            this.loading = true
            return new Promise((resolve, reject) => {
                const {
                    sortBy,
                    descending,
                    page,
                    rowsPerPage
                } = this.pagination

                let items = this.getUsers()
                const total = items.length

                if (this.pagination.sortBy) {
                    items = items.sort((a, b) => {
                        const sortA = a[sortBy]
                        const sortB = b[sortBy]

                        if (descending) {
                            if (sortA < sortB) return 1
                            if (sortA > sortB) return -1
                            return 0
                        } else {
                            if (sortA < sortB) return -1
                            if (sortA > sortB) return 1
                            return 0
                        }
                    })
                }

                if (rowsPerPage > 0) {
                    items = items.slice((page - 1) * rowsPerPage, page * rowsPerPage)
                }

                setTimeout(() => {
                    this.loading = false
                    resolve({
                        items,
                        total
                    })
                }, 1000)
            })
        },
        getUsers() {
            return [{
                    value: false,
                    name: 'Frozen Yogurt',
                    calories: 159,
                    fat: 6.0,
                    carbs: 24,
                    protein: 4.0,
                    sodium: 87,
                    calcium: '14%',
                    iron: '1%'
                },
                {
                    value: false,
                    name: 'Ice cream sandwich',
                    calories: 237,
                    fat: 9.0,
                    carbs: 37,
                    protein: 4.3,
                    sodium: 129,
                    calcium: '8%',
                    iron: '1%'
                },
                {
                    value: false,
                    name: 'Eclair',
                    calories: 262,
                    fat: 16.0,
                    carbs: 23,
                    protein: 6.0,
                    sodium: 337,
                    calcium: '6%',
                    iron: '7%'
                },
                {
                    value: false,
                    name: 'Cupcake',
                    calories: 305,
                    fat: 3.7,
                    carbs: 67,
                    protein: 4.3,
                    sodium: 413,
                    calcium: '3%',
                    iron: '8%'
                },
                {
                    value: false,
                    name: 'Gingerbread',
                    calories: 356,
                    fat: 16.0,
                    carbs: 49,
                    protein: 3.9,
                    sodium: 327,
                    calcium: '7%',
                    iron: '16%'
                },
                {
                    value: false,
                    name: 'Jelly bean',
                    calories: 375,
                    fat: 0.0,
                    carbs: 94,
                    protein: 0.0,
                    sodium: 50,
                    calcium: '0%',
                    iron: '0%'
                },
                {
                    value: false,
                    name: 'Lollipop',
                    calories: 392,
                    fat: 0.2,
                    carbs: 98,
                    protein: 0,
                    sodium: 38,
                    calcium: '0%',
                    iron: '2%'
                },
                {
                    value: false,
                    name: 'Honeycomb',
                    calories: 408,
                    fat: 3.2,
                    carbs: 87,
                    protein: 6.5,
                    sodium: 562,
                    calcium: '0%',
                    iron: '45%'
                },
                {
                    value: false,
                    name: 'Donut',
                    calories: 452,
                    fat: 25.0,
                    carbs: 51,
                    protein: 4.9,
                    sodium: 326,
                    calcium: '2%',
                    iron: '22%'
                },
                {
                    value: false,
                    name: 'KitKat',
                    calories: 518,
                    fat: 26.0,
                    carbs: 65,
                    protein: 7,
                    sodium: 54,
                    calcium: '12%',
                    iron: '6%'
                }
            ]
        }
    }
})

Short answer is use computed properties to decide what columns are going to be included.简短的回答是使用计算属性来决定将包含哪些列。

Your data table is taking a list of headers and a list of items (rows).您的数据表采用标题列表和项目(行)列表。 I've added a couple of computed properties to your Vue to return the list of columns that should be included in the data table results.我已经向您的 Vue 添加了几个计算属性,以返回包含在数据表结果中的列列表。

computed:{
  filteredHeaders(){
    return this.headers.filter(h => h.selected)
  },
  filteredItems(){
    return this.items.map(item => {
      let filtered = Object.assign({}, item)
      this.headers.forEach(header => {
        if (!header.selected) delete filtered[header.value]
      })
      return filtered
    })
  }
},

Notice that these computed values are using a property of the header called selected .请注意,这些计算值使用了名为selected的标题的属性。 I added that property to your list of headers to allow you to select the headers that are going to be included in the output.我将该属性添加到您的标题列表中,以允许您选择将包含在输出中的标题。

{
  text: 'Fat (g)',
  value: 'fat',
  selected: true
},

Next, your checkboxes need to use that property as their model.接下来,您的复选框需要使用该属性作为它们的模型。

<v-checkbox v-bind:label="header.text" v-model="header.selected" :value="header.selected" ></v-checkbox>

Finally, you have a template for each row.最后,每一行都有一个模板。 I modified that to check to see if each column is enabled.我修改了它以检查是否启用了每列。

<template slot="items" scope="props">
  <td v-if="showColumn('name')">{{ props.item.name }}</td>
  <td v-if="showColumn('calories')"  class="text-xs-right">{{ props.item.calories }}</td>
  <td v-if="showColumn('fat')"  class="text-xs-right">{{ props.item.fat }}</td>
  <td v-if="showColumn('carbs')"  class="text-xs-right">{{ props.item.carbs }}</td>
  <td v-if="showColumn('protein')"  class="text-xs-right">{{ props.item.protein }}</td>
  <td v-if="showColumn('sodium')"  class="text-xs-right">{{ props.item.sodium }}</td>
  <td v-if="showColumn('calcium')"  class="text-xs-right">{{ props.item.calcium }}</td>
  <td v-if="showColumn('iron')"  class="text-xs-right">{{ props.item.iron }}</td>
</template>

And here is the showColumn method that is used in that template.这是该模板中使用的showColumn方法。

showColumn(col){
  return this.headers.find(h => h.value === col).selected
},

Finally, here is a working example .最后,这是一个工作示例

Obviously this is not tuned or anything, it's just an initial "get it working" version.显然这没有经过调整或任何东西,它只是一个初始的“让它工作”的版本。 But it should get you going.但它应该让你前进。

只需设置fields属性以仅定义您希望显示的列。

Loop all the fields as well也循环所有字段

example : <b-table striped hover :items="items" :fields="fields"></b-table>示例: <b-table striped hover :items="items" :fields="fields"></b-table>

Enjoy.享受。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM