Vue组件全部作为一个组件

时间:2019-07-10 06:47:24

标签: vue.js

我有三个组成部分。它们都绑定一个值。

下面是具有三个组成部分的刀片文件

刀片文件:

<div id="app">
    <div class="row">
        <div class="col-4">
            <crud-component :type="'tower'"></crud-component>
        </div>
        <div class="col-4">
            <crud-component :type="'country'"></crud-component>
        </div>

        <div class="col-4">
            <crud-component :type="'department'"></crud-component>
        </div>
    </div>
</div>

所有这些组件都是动态的,它们仅依赖于称为:type

的绑定值

Vue文件:

<template>
    <div>
        <h3>{{capitalize(type)}} <button class="btn btn-primary btn-sm" @click="showAddModal()">Add</button></h3>
        <datatable :columns="columns" :sortKey="sortKey" :sortOrders="sortOrders">
            <tbody v-if="loading">
                <tr>
                    <td colspan="11"><div class="lds-dual-ring mx-auto"></div></td>
                </tr>
            </tbody>
            <tbody v-else>
                <tr v-for="data in retData" :key="data.id">
                    <td> {{data.id}}</td>
                    <td> {{data.name}}</td>
                    <td>
                        <button class="btn btn-warning btn-sm" @click="showEditModal(data)"> Edit </button>
                        <button class="btn btn-danger btn-sm" @click="showDeleteModal(data)"> Delete </button>
                    </td>
                </tr>
            </tbody>
        </datatable>

        <!-- MODALS -->
        <modal :name="type + '-add-modal'" height="auto">
            <div class="row p-3">
                <div class="col-12">
                    <h3>Add {{capitalize(type)}}</h3>
                    <hr>
                    <form>
                        <div class="form-group">
                            <label for="add-item">{{capitalize(type)}} Name</label>
                            <input v-validate="'required'" type="text" name="item-name" class="form-control" id="add-item-name" required>
                            <small class="form-text text-danger">{{errors.first('item-name')}}</small>
                        </div>
                        <button type="button" class="float-right btn btn-sm btn-primary" @click="store">Submit</button>
                    </form>
                </div>
            </div>
        </modal>

        <modal :name="type + '-edit-modal'" height="auto">
            <div class="row p-3">
                <div class="col-12">
                    <h3>Edit {{capitalize(type)}}</h3>
                    <hr>
                    <form>
                        <div class="form-group">
                            <label for="edit-item">{{capitalize(type)}} Name</label>
                            <input v-validate="'required'" name="item-name" type="text" class="form-control" id="edit-item-name" v-model="currentItem.name" required>
                            <small class="form-text text-danger">{{errors.first('item-name')}}</small>
                        </div>
                        <button type="button" class="float-right btn btn-sm btn-primary" @click="store">Submit</button>
                    </form>
                </div>
            </div>
        </modal>

        <modal :name="type +  '-delete-modal'" height="auto">
            <div class="row p-3">
                <div class="col-12">
                    <h3>Delete {{capitalize(type)}}</h3>
                    <hr>
                    <p class="lead">Are you sure you want to delete <strong>{{currentItem.name}}</strong>?</p>
                    <button type="button" class="float-right btn btn-sm btn-primary" @click="destroy">Submit</button>
                </div>
            </div>
        </modal>
    </div>
</template>


<script>
import Datatable from './utilities/DatatableComponent.vue';
import Pagination from './utilities/PaginationComponent.vue';
export default {
    components: {
        'datatable': Datatable,
        'pagination': Pagination,
    },
    props: ['type'],
    mounted() {
        this.get(this.type);
    },
    data() {
        let sortOrders = {};
        let columns = [
            {label: 'ID', name:'id', isSortable: true},
            {label: 'NAME', name:'name', isSortable: true},
            {label: 'ACTIONS', name:'actions', isSortable: false}
        ];
        columns.forEach(column => {
            sortOrders[column.name] = -1;
        });
        return {
            loading: true,
            currentItem: '',
            isUpdate: false,
            sortKey: 'id',
            columns: columns,
            sortOrders: sortOrders,
            tableData: {
                draw: 0,
                length: 10,
                search: '',
                column: 'id',
                dir: 'desc',
            },
            pagination: {
                lastPage: '',
                currentPage: '',
                total: '',
                lastPageUrl: '',
                prevPageUrl: '',
                nextPageUrl: '',
                from: '',
                to: '',
            },
            retData: []
        };
    },
    methods: {
        showEditModal(item) {
            this.currentItem = item;
            this.$modal.show(this.type + '-edit-modal');
            this.isUpdate = true;
        },
        showAddModal() {
            this.$modal.show(this.type + '-add-modal');
        },
        store() {
            this.$validator.validate().then(valid => {
                if(!valid) {
                    return;
                } else {
                    if(this.isUpdate == true) {
                        axios.post('/api/crud/store', {
                            type: this.type,
                            item: this.currentItem,
                            isUpdate: this.isUpdate
                        }).then(response => {
                            this.get(this.type);
                            this.$modal.hide(this.type + '-edit-modal');
                            this.isUpdate = false;
                            this.currentItem = '';
                        });
                    }  else {
                        axios.post('/api/crud/store', {
                            type: this.type,
                            name: $('#add-item-name').val(),
                            isUpdate: this.isUpdate
                        }).then(response => {
                            this.get(this.type);
                            this.$modal.hide(this.type + '-add-modal');
                        });
                    }
                }
            });
        },
        showDeleteModal(item) {
            this.currentItem = item;
            this.$modal.show(this.type + '-delete-modal');
        },
        destroy() {
            axios.delete('/api/crud/delete', {
                data: {
                    type: this.type,
                    item: this.currentItem
                }
            }).then(response => {
                this.$modal.hide(this.type + '-delete-modal')
                this.currentItem = '';
                this.get(this.type)
            });
        },
        capitalize(s) {
            if (typeof s !== 'string') return ''
            return s.charAt(0).toUpperCase() + s.slice(1)
        },
        get(type) {
            axios.interceptors.request.use(config => {
                NProgress.start();
                this.loading = true;
                return config;
            });

            axios.interceptors.response.use(response => {
                NProgress.done();
                this.loading = false;
                return response;
            });

            this.tableData.draw++;
            axios.post('/api/crud', {
                type: type,
                tableData: this.tableData
            }).then(response => {
                let data = response.data;
                if(this.tableData.draw == data.draw) {
                    this.retData = data.data.data
                }
                console.log('Done');
            });
        },
    }
}
</script>
<style>
.lds-dual-ring {
    display: block;
    width: 64px;
    height: 64px;
}
.lds-dual-ring:after {
    content: " ";
    display: block;
    width: 46px;
    height: 46px;
    margin: 5px;
    border-radius: 50%;
    border: 5px solid #000;
    border-color: #000 transparent #000 transparent;
    animation: lds-dual-ring 1.2s linear infinite;
}
@keyframes lds-dual-ring {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}
</style>

问题是,当我尝试使用一个组件进行更新,获取或执行任何操作时。 它运行所有API调用以获取其特定数据。

All of the tables are loading

我只想在获取数据时加载一张表。

2 个答案:

答案 0 :(得分:0)

正如我在上面的评论中所提到的,每当您的任何组件调用其get方法时,您都将interceptors添加到您的Axios实例。

拦截器代码在通过Axios进行的每个请求/响应上运行,无论它来自何处。这就是为什么在发出请求时所有组件似乎都正在加载的原因。

我建议您删除拦截器并将代码更改为

get(type) {
  NProgress.start()
  this.loading = true
  this.tableData.draw++

  axios.post('/api/crud', {
    type: type,
    tableData: this.tableData
  }).then(response => {
    NProgress.done()
    this.loading = false
    let data = response.data;
    if(this.tableData.draw == data.draw) {
      this.retData = data.data.data
    }
  })
}

答案 1 :(得分:-1)

数据必须是一个函数。

data () {
    return {
        ...
    }
}

您不能简单地拥有一堆变量以及像您一样的函数。您需要重构组件。