ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 검색 필터 및 더보기 구현(#Filter #Search #LoadMore)
    Laravel/Inertia.js 2021. 11. 16. 15:16
    반응형
    SMALL

    # What?

    스크롤 유지하면서 리스트 필터링 및 더보기 구현

     

    # Why?

    요즘은 페이지 바뀌면서 스크롤 초기화되는거 지양

     

    # How?

    1. form을 watch로 검사하지 말고 각 input에 @change를 걸어 filter 메소드 호출하게 하기

     

    2.  preserveScroll : true 옵션으로 스크롤 유지하기

     

    3. replace: true 옵션으로 페이지 히스토리를 남기지 않고 뒤로가기 시 진짜 이전 페이지로 이동하게끔 하기(안그러면 필터값 바꿀때마다의 페이지 히스토리 다 남아서 뒤로가기 시 몇번을 눌러대야함)

     

    4. preserveState : true 옵션으로 더보기 구현 시 이전 데이터 리스트에 새로 불러온 데이터 리스트를 추가하기

     

    <template>
        <div class="subContent area-workerList">
            <div class="wrap">
                <div class="m-input-checkboxes type01">
                    <div class="m-input-checkbox type01">
                        <input type="checkbox" checked="checked" v-if="form.category_ids.length === 0">
                        <input type="checkbox" v-else>
                        <label for="" @click="clearCategories">전체</label>
                    </div>
                    <div class="m-input-checkbox type01" v-for="category in categories.data" :key="category.id" @change="filter">
                        <input type="checkbox" :id="category.id" :value="category.id" v-model.lazy="form.category_ids">
                        <label :for="category.id">{{ category.title }}</label>
                    </div>
                </div>
    
                <div class="m-input-top type01">
                    <div class="inputs">
                        <div class="m-input-select type01">
                            <select name="" id="" v-model.lazy="form.orderBy" @change="filter">
                                <option value="count_request">인기순</option>
                                <option value="created_at">최신순</option>
                            </select>
                        </div>
    
                        <form @submit.prevent="filter">
                            <div class="m-input-text type01">
                                <input type="text" placeholder="전문가명" v-model.lazy="form.word">
    
                                <img src="/img/search.png" alt="" class="m-input-text-deco" @click="filter">
                            </div>
                        </form>
                    </div>
                </div>
    
                <div class="m-empty type01" v-if="workers.data.length === 0">
                    데이터가 없습니다.
                </div>
    
                <workers :items="workers.data" v-else />
    
                <div class="m-btns type01 mt-80" v-if="workers.links.next">
                    <button class="m-btn type01 bg-primary" @click="loadMore">더보기</button>
                </div>
            </div>
        </div>
    </template>
    <script>
    import Workers from "../../Components/Workers";
    export default {
        components: {Workers},
    
        data() {
            return {
                workers: this.$page.props.workers,
                categories: this.$page.props.categories,
                form: this.$inertia.form({
                    word: this.$page.props.word,
                    orderBy: this.$page.props.orderBy,
                    category_ids: this.$page.props.category_ids,
                    page: 1
                }),
                loading: false,
            }
        },
    
        methods: {
            clearCategories(){
                this.form.category_ids = [];
    
                this.filter();
            },
    
            loadMore(){
                if(!this.loading){
                    this.form.page += 1;
    
                    this.filter();
                }
            },
    
            filter(){
                let isLoadMore = this.workers.meta.current_page !== this.form.page;
    
                this.loading = true;
    
                if(!isLoadMore)
                    this.form.page = 1;
    
                this.form.get("/workers", {
                    preserveScroll: true,
                    preserveState: true,
                    replace: true,
                    immediate: true,
                    onSuccess: (response) => {
                        this.loading = false;
    
                        if(isLoadMore) {
                            return this.workers = {
                                ...response.props.workers,
                                data: [...this.workers.data, ...response.props.workers.data]
                            }
                        }
    
                        return this.workers = response.props.workers;
                    }
                });
            }
        },
    
        mounted() {
    
        }
    }
    </script>
    LIST

    'Laravel > Inertia.js' 카테고리의 다른 글

    Inertia.js에서 AOS 사용하는법  (0) 2022.05.21
    Inertia.js 외부링크로 redirect하는법(결제 요청 시 필요)  (0) 2022.05.13
    Shared Data  (0) 2021.09.21
    레이아웃 설정법  (0) 2021.09.21
    초기세팅  (0) 2021.09.07

    댓글

Designed by Tistory.