使用compute过滤元素:VueJS中的分页问题

时间:2018-08-20 10:22:39

标签: search vue.js filter vuejs2 paginate

我正在使用Laravel和VueJs,

我正在尝试以下操作:我创建了一个搜索栏,以按用户名,姓氏或电子邮件查找用户。

我曾经使用计算来编写过滤器,但我意识到我的过滤器仅对前10个元素进行过滤(因为我正在使用分页显示存储在数据库中的所有用户)

...我该怎么做才能使我的过滤器在我的所有用户上都能正常使用,而不是每十个给我一次分页服务(如果可以的话,请保持分页)?

这是我的脚本和模板(非常感谢):

<script>

    import UpdateProfile from './users/UpdateProfile';
    import CreateUser from './users/CreateUser';
    import User from '../models/user';

    export default {
        components: {UpdateProfile, CreateUser},

        data() {
            return {
                showUpdateModal: false,
                showCreateModal: false,
                users: [],
                user: new User(),
                search:'',
                paginator: {
                    current: 1,
                    total: 1,
                    limit: 10,
                }
            }
        },

        mounted() {
            this.goToPage(1);
        },

        methods: {
            userPermissions(user) {
                return this.CONSTANTS.getUserType(user.permissions);
            },
            addUser(user) {
                this.showCreateModal = false;
                this.api.post('/users', user).then(() => {
                    this.goToPage(this.paginator.current);
                });
            },
            editUser(user) {
                this.user = JSON.parse(JSON.stringify(user));
                this.showUpdateModal = true;
            },
            updateUser(user) {
                this.showUpdateModal = false;
                this.api.put('/users/' + user.id, user).then(() => {
                    this.goToPage(this.paginator.current)
                });
            },
            deleteUser(user) {
                this.api.delete('/users/' + user.id).then(() => {
                    this.goToPage(this.paginator.current)
                });
            },
            navigatePrev(page) {
                this.goToPage(page)
            },
            navigateNext(page) {
                this.goToPage(page)
            },
            goToPage(page) {
                this.api.get('/users?page=' + page + '&limit=' + this.paginator.limit).then(response => {
                    this.users = response.data;
                    this.paginator = response.paginator;
                });
            }
        },

        computed:{
            filteredUsers: function () {
                return this.users.filter((user) => {

                    var searchByName = user.name.toLowerCase().match(this.search.toLowerCase());
                    var searchByLastName = user.lastname.toLowerCase().match(this.search.toLowerCase());
                    var searchByEmail = user.email.toLowerCase().match(this.search.toLowerCase());

                    if(searchByName){
                        return searchByName;
                    }

                    if(searchByLastName){
                        return searchByLastName;
                    }

                    if(searchByEmail){
                        return searchByEmail;
                    }

                });
            }
        }
    }
</script>
<template>

    <div class="container">

        <div class="button is-primary" @click="showCreateModal=true" v-if="CONSTANTS.hasRootPermissions()">
            <span class="icon"><i class="fas fa-plus fa-lg"></i></span>
            <span>Add User</span>
        </div>
        <br><br>

        <create-user v-if="CONSTANTS.hasRootPermissions()"
                     :show="showCreateModal"
                     v-on:save="addUser"
                     v-on:close="showCreateModal=false"/>

        <!--Search Users-->
        <div class="control is-expanded">
            <h1>Search users</h1>
            <input class="input" type="text" v-model="search" placeholder="Find a user"/>
        </div>
        <br><br>
        <!--Search Users-->

        <table class="table">

            <thead>
            <tr>
                <th>Name</th>
                <th>Last Name</th>
                <th>Email</th>
                <th>Admin</th>
                <th>Permissions</th>
                <th></th>
                <th></th>
            </tr>
            </thead>

            <tbody>
            <tr v-for="user in filteredUsers">
                <td>{{user.name}}</td>
                <td>{{user.lastname}}</td>
                <td>{{user.email}}</td>
                <td>{{user.isAdmin ? 'yes' : 'no'}}</td>
                <td>{{userPermissions(user)}}</td>
                <td>
                    <div class="button is-info" @click="editUser(user)">
                        <span class="icon"><i class="far fa-edit"></i></span>
                        <span>Edit</span>
                    </div>
                </td>
                <td>
                    <div class="button is-danger" @click="deleteUser(user)">
                        <span class="icon"><i class="far fa-trash-alt"></i></span>
                        <span>Delete</span>
                    </div>
                </td>
            </tr>
            </tbody>

        </table>

        <paginator :paginator="paginator" v-on:prev="navigatePrev" v-on:next="navigateNext"/>

        <update-profile :data="user" :show="showUpdateModal" v-on:save="updateUser" v-on:close="showUpdateModal=false"/>

    </div>

</template>

1 个答案:

答案 0 :(得分:1)

您可以在开始时就获取所有用户(如果不是太多数据),然后在客户端对它们进行分页。

类似的东西:

    mounted() {
        this.api.get('/users').then(response => {
            this.users = response.data;
            this.paginator.total = Math.ceil(this.users.length / this.paginator.limit);
            });
    },

    methods: {
        goToPage(page) {
            this.paginator.current = page;
        }
    },

    computed:{
        filteredUsers: function () {
            return this.users.filter((user) => {

                var searchByName = user.name.toLowerCase().match(this.search.toLowerCase());
                var searchByLastName = user.lastname.toLowerCase().match(this.search.toLowerCase());
                var searchByEmail = user.email.toLowerCase().match(this.search.toLowerCase());

                if(searchByName){
                    return searchByName;
                }

                if(searchByLastName){
                    return searchByLastName;
                }

                if(searchByEmail){
                    return searchByEmail;
                }

            }).filter((el, index) => {

                return (   index >= (this.paginator.current - 1) * this.paginator.limit
                        && index < this.paginator.current * this.paginator.limit);
            });
        }
    }
}

更新

其他选择是在服务器端执行Serching并在每个页面请求中发送搜索字符串:

    methods: {
        goToPage(page) {
            this.api.get('/users?page=' + page + '&limit=' + this.paginator.limit
                         + '&search=' + this.search).then(response => {

                this.users = response.data;
                this.paginator = response.paginator;
            });
        },

        performSearch() {
            this.goToPage(1);
        },
    },
}

在模板中带有搜索块:

    <!--Search Users-->
    <div class="control is-expanded">
        <h1>Search users</h1>
        <input class="input" type="text"
               v-model="search" placeholder="Find a user"
               @change="performSearch"/>
    </div>

您可以在输入或添加“搜索”后添加反跳以获得结果。搜索字段后面的按钮以触发performSearch()

    <!--Search Users-->
    <div class="control is-expanded">
        <h1>Search users</h1>
        <input class="input" type="text"
               v-model="search" placeholder="Find a user"/>
        <button @click="performSearch">Search!</button>
    </div>