代码之家  ›  专栏  ›  技术社区  ›  dukedevil294

Vue-更新引导表自定义组件上的数据

  •  1
  • dukedevil294  · 技术社区  · 7 年前

    我正在尝试在Vue 2.0中创建一个自定义组件,以扩展引导Vue库的现有功能 <b-table>

    data

    因此,我知道我有点接近,但我真的很感激任何关于如何使其正确工作的见解,以及我可以改进此组件任何部分的方法。

    OreillyTable.vue.js

    const OreillyTable =  {
    inheritAttrs: false,
    data: function () {
        return {
            filter: null,
            sortDesc: false,
            hideEmpty: false,
            isBusy: false,
            currentPage: 1,
            data: null
        }
    },
    mounted: function () {
        let filtered = this.slots.filter(function(value, index, arr){
            return value.customRender;
        });
        this.slots = filtered;
    },
    methods: {
        oreillyTableSort (a, b, key) {
            if (a[key] === null || b[key] === null) {
                return a[key] === null && b[key] !== null ? -1 : (a[key] !== null && b[key] === null ? 1 : 0);
            } else if (typeof a[key] === 'number' && typeof b[key] === 'number') {
                // If both compared fields are native numbers
                return a[key] < b[key] ? -1 : (a[key] > b[key] ? 1 : 0)
            } else {
                // Stringify the field data and use String.localeCompare
                return this.toString(a[key]).localeCompare(this.toString(b[key]), undefined, {
                    numeric: true
                });
            }
        },
    
        toString (val) {
            return typeof val !== "undefined" && val != null ? val.toString() : '';
        },
    
        oreillyFilter (filteredItems) {
            this.totalRows = filteredItems.length;
            this.currentPage = 1;
        }
    },
    props: {
        fields: {
            type: Array
        },
        items: {
            type: Array,
            required: true
        },
        hideEmpty: {
            type: Boolean
        },
        filterPlaceholder: {
            type: String,
            default: "Filter"
        },
        sortFunction: {
            type: Function,
            default: null
        },
        filterFunction: {
            type: Function,
            default: null
        },
        slots: {
            type: Array
        },
        sortBy: {
            type: String,
            default: null
        },
        perPage: {
            type: Number,
            default: 10
        },
        value: {
    
        }
    },
    template: `<div :class="{ 'no-events' : isBusy }">
                <b-row>
                    <b-col md="12">
                        <b-form-group class="mb-2 col-md-3 float-right pr-0">
                            <b-input-group>
                                <b-form-input v-model="filter" :placeholder="filterPlaceholder" class="form-control" />
                            </b-input-group>
                        </b-form-group>
                    </b-col>
                </b-row>
                <div class="position-relative">
                    <div v-if="isBusy" class="loader"></div>
                    <b-table stacked="md" outlined responsive striped hover
                        v-bind="$attrs"
                        v-model="data"
                        :show-empty="!hideEmpty"
                        :items="items"
                        :fields="fields"
                        :no-provider-sorting="true" 
                        :no-sort-reset="true"
                        :filter="filter"
                        :sort-by.sync="sortBy" 
                        :sort-desc.sync="sortDesc" 
                        :sort-compare="sortFunction === null ? this.oreillyTableSort : sortFunction" 
                        :busy.sync="isBusy"
                        :current-page="currentPage"
                        :per-page="perPage"
                        @filtered="filterFunction === null ? this.oreillyFilter : filterFunction">
    
                        <template :slot="slot.key" slot-scope="row" v-for="slot in slots">
                            <slot :name="slot.key" :data="row"></slot>
                        </template>
                    </b-table>
    
                    <b-row v-if="items.length > perPage">
                        <b-col sm="12">
                            <b-pagination size="md" :total-rows="items.length" v-model="currentPage" :per-page="perPage"></b-pagination>
                        </b-col>
                    </b-row>
                </div>
            </div>`
    };
    

    <script>
    Vue.use(window.vuelidate.default);
    
    Vue.component('oreilly-table', OreillyTable);
    
    const dashboardItems = [
        { id: 12, firstName: "John", lastName: "Adams", tmNumber: "588999", team: "Corporate", flapjackCount: 4, enrollDate: "2018-11-05" },
        { id: 13, firstName: "George", lastName: "Washington", tmNumber: "422111", team: "America", flapjackCount: 28, enrollDate: "2018-10-01" },
        { id: 14, firstName: "Abraham", lastName: "Lincoln", tmNumber: "358789", team: "America", flapjackCount: 16, enrollDate: "2017-09-02" },
        { id: 15, firstName: "Jimmy", lastName: "Carter", tmNumber: "225763", team: "Core", flapjackCount: 9, enrollDate: "2018-03-02" },
        { id: 16, firstName: "Thomas", lastName: "Jefferson", tmNumber: "169796", team: "Core", flapjackCount: 14, enrollDate: "2018-05-01" }
    ];
    
    const Dashboard = {
        template: `<jsp:include page="dashboard.jsp"/>`,
        data: function(){
            return {            
                notification: {
                    text: "The Great Flapjack Contest will be held on December 25, 2018.",
                    variant: "primary",
                    timer: true
                },
                fields: [
                    { key: "name", label: "Name", sortable: true, customRender: true },
                    { key: "team", label: "Team", sortable: true },
                    { key: "enrollDate", label: "Enrollment Date", sortable: true, formatter: (value) => {return new Date(value).toLocaleDateString();} },
                    { key: "flapjackCount", sortable: true },
                    { key: "id", label: "", 'class': 'text-center', customRender: true }
                ]
            }
        },
        methods: {
            removeRow: function(id) {
                this.$refs.table.isBusy = true;
                setTimeout(() => { console.log("Ajax Request Here"); this.$refs.table.isBusy = false; }, 1000);
                const index = this.$refs.table.data.findIndex(item => item.id === id) 
                if (~index) 
                    this.$refs.table.data.splice(index, 1)  
            },
            resetData: function() {
                this.$refs.table.data = dashboardItems;
            }
        }
    };
    
    const router = new VueRouter({
        mode: 'history',
        base: "/ProjectTemplate/flapjack",
        routes: [
            { path: '/enroll', component: Enroll },
            { path: '/', component: Dashboard },
            { path: '/404', component: NotFound },  
            { path: '*', redirect: '/404' }
        ]
    });
    
    new Vue({router}).$mount('#app');
    

    dashboard.jsp

    <compress:html>
    <div>
        <oreilly-table ref="table" :items="dashboardItems" :slots="fields" :fields="fields">
            <template slot="name" slot-scope="row">
                {{ row.data.item.firstName }} {{ row.data.item.lastName }} ({{ row.data.item.tmNumber }})
            </template>
            <template slot="id" slot-scope="row">
                <a href="#" @click.prevent="removeRow(row.data.item.id)">Remove</a>
            </template>
        </oreilly-table>
        <footer class="footer position-sticky fixed-bottom bg-light">
            <div class="container text-center">
                <router-link tag="button" class="btn btn-outline-secondary" id="button" to="/enroll">Enroll</router-link>
                &emsp;
                <b-button @click.prevent="resetData" size="md" variant="outline-danger">Reset</b-button>
            </div>
        </footer>
    </div>
    

    1 回复  |  直到 7 年前
        1
  •  4
  •   Kimberley    7 年前

    我试图用一个简单的例子来重现您的问题(参见: https://codesandbox.io/s/m30wqm0xk8?module=%2Fsrc%2Fcomponents%2FGridTest.vue )我遇到了和你一样的问题。正如其他人已经说过的,我同意重置原始数据的最简单方法是复制。我编写了两种方法来删除和重置数据。

    methods: {
        removeRow(id) {
          const index = this.records.findIndex(item => item.index === id);
    
          this.records.splice(index, 1);
        },
        resetData() {
          this.records = this.copyOfOrigin.slice(0);
        }
      }
    

    Vue docs

    mounted: function() {
        this.copyOfOrigin = this.records.slice(0);
      } 
    

    现在,您可以简单地删除记录,但也可以重置所有数据。

    SEE FULL DEMO

    推荐文章