Первоначально хотел сделать загрузку новых элементов при прокрутке до конца страницы, но решил ограничится кнопкой, т.к. работа с отслеживанием скрола, это дополнительное усложнение кода, которое к 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);