WEB API 는 무료 오픈 사이트인 "https://jsonplaceholder.typicode.com/posts " 를 활용하였습니다. 
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue.js Example with Server-Side Pagination</title>
    <!-- Include Vue.js, Axios, and Bootstrap CDN -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
    <div id="app" class="container">
        <ul class="list-group">
            <li class="list-group-item" v-for="post in paginatedPosts" :key="post.id">
                {{ post.title }}
            </li>
        </ul>
        <ul class="pagination">
            <li><button class="btn btn-primary" @click="goToFirstPage">◀◀ 처음</button></li>
            <li><button class="btn btn-primary" @click="previousPageGroup" :disabled="pageGroup === 1">◀ 이전</button>
            </li>
            <li v-for="pageNumber in pageGroupNumbers" :key="pageNumber">
                <button class="btn btn-primary" @click="goToPage(pageNumber)" :disabled="currentPage === pageNumber">
                    {{ pageNumber }}
                </button>
            </li>
            <li><button class="btn btn-primary" @click="nextPageGroup"
                    :disabled="pageGroup * pageGroupSize >= totalPageNumbers">다음 ▶</button>
            <li><button class="btn btn-primary" @click="goToLastPage">마지막 ▶▶</button></li>
            </li>
        </ul>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                posts: [],
                pageSize: 12,
                currentPage: 1,
                totalCount: 0,
                pageGroup: 1,
                pageGroupSize: 10,
            },
            computed: {
                totalPageNumbers() {
                    return Math.ceil(this.totalCount / this.pageSize);
                },
                paginatedPosts() {
                    return this.posts;
                },
                pageGroupNumbers() {
                    let start = (this.pageGroup - 1) * this.pageGroupSize + 1;
                    let end = start + this.pageGroupSize;
                    let numbers = [];
                    for (let i = start; i < end; i++) {
                        if (i <= this.totalPageNumbers) {
                            numbers.push(i);
                        }
                    }
                    return numbers;
                },
            },
            methods: {
                fetchData(page) {
                    axios.get(`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=${this.pageSize}`)
                        .then(response => {
                            this.posts = response.data;
                            this.totalCount = parseInt(response.headers['x-total-count']) || 0;
                        })
                        .catch(error => {
                            console.error('Error fetching data from API:', error);
                        });
                },
                goToPage(pageNumber) {
                    this.currentPage = pageNumber;
                    this.fetchData(pageNumber);
                },
                nextPageGroup() {
                    if (this.pageGroup * this.pageGroupSize < this.totalPageNumbers) {
                        this.pageGroup++;
                        this.goToPage((this.pageGroup - 1) * this.pageGroupSize + 1);
                    }
                },
                previousPageGroup() {
                    if (this.pageGroup > 1) {
                        this.pageGroup--;
                        this.goToPage((this.pageGroup - 1) * this.pageGroupSize + 1);
                    }
                },
                goToFirstPage() {
                    this.currentPage = 1;
                    this.pageGroup = 1;
                    this.fetchData(this.currentPage);
                },
                goToLastPage() {
                    this.currentPage = this.totalPageNumbers;
                    this.pageGroup = Math.ceil(this.totalPageNumbers / this.pageGroupSize);
                    this.fetchData(this.currentPage);
                },
            },
            mounted() {
                this.fetchData(this.currentPage);
            }
        });
    </script>
    <style>
        .pagination {
            list-style: none;
            display: flex;
            margin: 10px 0;
        }
        .pagination li {
            margin-right: 5px;
        }
        .pagination button {
            padding: 5px 10px;
        }
    </style>
</body>
</html> 
 
실행한 화면 
 
 
 
 computed 설명  
 
 
computed: {
    fullname: {
        get: function() {
            return this.firstname + ' ' + this.lastname;
        },
        set: function(newValue) {
            var names = newValue.split(' ');
            this.firstname = names[0];
            this.lastname = names[names.length - 1];
        }
    }
} 
위의 코드에서 fullname은 get 메서드를 통해 firstname과 lastname을 합쳐 반환하고, set 메서드를 통해 fullname에 새 값을 할당할 때 이를 분리하여 firstname과 lastname에 할당합니다. 
 
 
 
 methods:   
 
메서드를 정의하는 옵션입니다. 이는 컴포넌트에서 사용할 함수를 정의하는 곳입니다. 메서드는 호출될 때마다 실행되므로, 캐싱은 이루어지지 않습니다. 이는 사용자의 액션에 응답하거나, 반복적으로 사용하는 함수를 정의하는데 사용됩니다. 메서드는 계산된 속성과는 달리, 파라미터값을 받을 수 있습니다  
 
 
 
methods: {
    greet: function(time, name) {
        return 'Good ' + time + ', ' + name;
    }
} 
 
위의 코드에서 greet 메서드는 time과 name 두 가지 인자를 받아 문자열을 반환합니다. 
 
 
따라서, computed와 methods 중 어떤 것을 사용할지 결정할 때는, 연산 결과를 캐싱할 필요가 있거나 종속된 데이터에 따라 결과가 변하는 경우에는 computed 동적인 행동을 정의하거나 사용자의 액션에 응답해야 하는 경우에는 methods  
    
    
   
 
 
 
이전, 다음 기능만 넣고자 한다면? 
 
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue.js Simplified Pagination Example</title>
    <!-- Include Vue.js, Axios, and Bootstrap CDN -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
    <div id="app" class="container">
        <ul class="list-group">
            <li class="list-group-item" v-for="post in posts" :key="post.id">
                {{ post.id }} {{ post.title }}
            </li>
        </ul>
        <div class="pagination">
            <button class="btn btn-primary" @click="previousPage" :disabled="currentPage === 1">이전</button>
            <button class="btn btn-primary" @click="nextPage" :disabled="currentPage >= totalPageNumbers">다음</button>
        </div>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                posts: [],
                pageSize: 5,
                currentPage: 1,
                totalCount: 0,
            },
            computed: {
                totalPageNumbers() {
                    return Math.ceil(this.totalCount / this.pageSize);
                },
            },
            methods: {
                fetchData(page) {                    
                    axios.get(`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=${this.pageSize}`)
                        .then(response => {
                            this.posts = response.data;
                            this.totalCount = parseInt(response.headers['x-total-count']) || 0;
                        })
                        .catch(error => {
                            console.error('Error fetching data from API:', error);
                        });
                },
                previousPage() {
                    if (this.currentPage > 1) {
                        this.currentPage--;
                        this.fetchData(this.currentPage);
                    }
                },
                nextPage() {
                    if (this.currentPage < this.totalPageNumbers) {
                        this.currentPage++;
                        this.fetchData(this.currentPage);
                    }
                },
            },
            mounted() {
                console.log(this.currentPage);
                this.fetchData(this.currentPage);
            }
        });
    </script>
    <style>
        .pagination {
            display: flex;
            justify-content: center;
            margin: 10px 0;
        }
    </style>
</body>
</html>