Тестируем Vue: "бесконечный скрол"

12.10.2019

Первоначально хотел сделать загрузку новых элементов при прокрутке до конца страницы, но решил ограничится кнопкой, т.к. работа с отслеживанием скрола, это дополнительное усложнение кода, которое к Vue отношения не имеет.

Итак, пользователь нажимает на кнопку "Еще" и загружается следующая пачка данных. Данные генерируются с помощью Faker

Стоит учитывать, что axios не входит в состав Vue и его нужно подключать отдельно, иначе получим ошибку
[Vue warn]: Error in v-on handler: "ReferenceError: axios is not defined"

Визуально:

pic1

Полный код:

 
<!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);


Категории: JavaScript, HTML
Яндекс.Метрика