Первоначально хотел сделать загрузку новых элементов при прокрутке до конца страницы, но решил ограничится кнопкой, т.к. работа с отслеживанием скрола, это дополнительное усложнение кода, которое к Vue отношения не имеет.
Тестируем Vue: "бесконечный скрол"
12.10.2019
Итак, пользователь нажимает на кнопку "Еще" и загружается следующая пачка данных. Данные генерируются с помощью Faker
Стоит учитывать, что axios не входит в состав Vue и его нужно подключать отдельно, иначе получим ошибку
[Vue warn]: Error in v-on handler: "ReferenceError: axios is not defined"
Визуально:
Полный код:
<!DOCTYPE HTML> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Vue ToDo List</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" rel="stylesheet"> </head> <body> <div id="VueApp1" class="container my-4"> <div class="row mb-2"> <div class="col-md-6"> <div class="row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative"> <div class="col p-4 d-flex flex-column position-static"> <strong class="d-inline-block mb-2 text-primary">World</strong> <h3 class="mb-0">Featured post</h3> <div class="mb-1 text-muted">Nov 12</div> <p class="card-text mb-auto">This is a wider card with supporting text below as a natural lead-in to additional content.</p> </div> </div> </div> <div class="col-md-6"> <div class="row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative"> <div class="col p-4 d-flex flex-column position-static"> <strong class="d-inline-block mb-2 text-success">Design</strong> <h3 class="mb-0">Post title</h3> <div class="mb-1 text-muted">Nov 11</div> <p class="mb-auto">This is a wider card with supporting text below as a natural lead-in to additional content.</p> </div> </div> </div> </div> <div class="row mb-2"> <div class="col-md-6" v-for="(item, index) in items"> <div class="row no-gutters border rounded overflow-hidden flex-md-row mb-4 shadow-sm h-md-250 position-relative"> <div class="col p-4 d-flex flex-column position-static"> <strong class="d-inline-block mb-2" :class="item.text_class">{{item.name}}</strong> <h3 class="mb-0">{{item.prof}}</h3> <div class="mb-1 text-muted">{{item.date}}</div> <p class="card-text mb-auto">{{item.text}}</p> </div> </div> </div> </div> <div class="row"> <div class="col-md-12"> <button @click="loadMore" class="btn btn-primary">Еще</button> </div> </div> </div> <!-- development version, includes helpful console warnings --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script> let vueApp1 = new Vue({ el: '#VueApp1', data: { items: [] }, methods: { loadMore: function () { axios .get('/api.php') .then(response => (this.items = this.items.concat(response.data))); }, }, mounted() { // First load this.loadMore(); } }) </script> </body> </html>
"API":
<? require_once 'vendor/autoload.php'; $faker = Faker\Factory::create('ru_RU'); $aRet = []; for($i = 0; $i < 2; $i++) { $aRet[] = [ 'name' => $faker->name, 'prof' => $faker->sentence($nbWords = 3, $variableNbWords = true), 'date' => $faker->dayOfMonth($max = 'now') . ' ' . $faker->monthName($max = 'now'), 'text' => $faker->text, 'text_class' => $faker->randomElement(['text-primary', 'text-secondary', 'text-success', 'text-danger', 'text-warning', 'text-info']), ]; } echo json_encode($aRet);