В первой части руководства мы узнали, как построить нашу серверную архитектуру с использованием Laravel 5.2 и различных маршрутов.

Мы начнем настройку представления внешнего интерфейса, где мы реализуем привязку модели представления, разработку на основе компонентов и шаблонов.

Как настроить начальный вид

Под общедоступным каталогом создайте новый файл с именем jobs.html. В этот файл добавьте обычные метаданные и добавьте ссылку на загрузку.

Фрагмент начальной загрузки

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">

И добавьте две ссылки, ссылающиеся на уменьшенную версию vue и плагин ресурсов vue.

jobs.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Job Board</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>

<body>

<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.17/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.7.0/vue-resource.js"></script>
</body>
</html>

Инициализация Vuejs

Нам нужно будет создать контейнер для инкапсуляции кода, который будет использовать vuejs. Под ним создайте заголовок и div v-app, как показано в приведенном ниже фрагменте кода.

v-app — это имя, присвоенное элементам div vuejs, которое позволяет их инициализировать и обрабатывать приложением vuejs.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Job Board</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>

<body>
<div class="container">
    <h1>Job Board</h1>
      <div id="v-app">
      
       </div><!-- /#v-app -->
</div><!-- /.container -->
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.17/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.7.0/vue-resource.js"></script>
</body>
</html>

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

Под div v-app добавьте таблицу, содержащую следующие определения.

<table class="table table-striped">
    <tr>
        <th>#</th>
        <th>Reference</th>
        <th>Title</th>
        <th>Type</th>
        <th>Description</th>
        <th>Employer</th>
        <th>Location</th>
        <th>Salary</th>
        <th>Post Date</th>
    </tr>    
</table>
<!-- /.table -->

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

<tr v-for="job in jobs" is="job" :job="job"></tr>

Добавьте указанный выше код чуть выше закрытия таблицы, как показано в приведенном ниже фрагменте кода:

<table class="table table-striped">
    <tr>
        <th>#</th>
        <th>Reference</th>
        <th>Title</th>
        <th>Type</th>
        <th>Description</th>
        <th>Employer</th>
        <th>Location</th>
        <th>Salary</th>
        <th>Post Date</th>
    </tr>
<tr v-for="job in jobs" is="job" :job="job"></tr>    
</table>
<!-- /.table -->

Мы добавим шаблон vuejs в наш код, чтобы помочь инкапсулировать наш код в легко повторно используемые фрагменты.

Прямо под шаблоном мы добавим набор тегов ‹p› и ‹pre›, чтобы мы могли вывести список вакансий на экран.

Добавьте следующий код под закрывающий тег таблицы:

<p class="lead">Here's a list of all your jobs.

</p>
<pre>{{ $data | json }}</pre>

Убедитесь, что ваш код похож на следующий:

<div class="container">
    <h1>Job Board</h1>
    <div id="v-app">
        <table class="table table-striped">
            <tr>
                <th>#</th>
                <th>Reference</th>
                <th>Title</th>
                <th>Type</th>
                <th>Description</th>
                <th>Employer</th>
                <th>Location</th>
                <th>Salary</th>
                <th>Post Date</th>
            </tr>
            <tr v-for="job in jobs" is="job" :job="job"></tr>
        </table>
        <!-- /.table -->
        <p class="lead">Here's a list of all your jobs.
 
        </p>
       <pre>{{ $data | json }}</pre>
  </div>
  <!-- /v-app -->
</div>
  <!-- /.container -->

Теперь у нас есть базовый кадр для вывода данных заданий на экран.

Следующим этапом является заполнение шаблона полями, содержащими данные, взятые из базы данных.

Вернитесь к своему шаблону и для каждой строки добавьте ссылку на поле из миграции таблицы заданий, которую мы объявили в части 1, как показано в этом фрагменте кода:

<template id="template-job-raw">
    <tr>
        <td>
            {{job.id}}
        </td>
        <td>
            {{ job.reference }}
        </td>
        <td>
            {{ job.title }}
        </td>
        <td>
            {{ job.type }}
        </td>
        <td>
            {{ job.description }}
        </td>
        <td>
            {{ job.location }}
        </td>
        <td>
            {{ job.employer }}
        </td>
        <td>
            {{ job.salary }}
        </td>
        <td>
            {{ job.post_date }}
        </td>
    </tr>

</template>
<!-- /#template-job-raw -->

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

Как добавить операции CRUD в наше представление?

Мы собираемся использовать следующие операции vuejs v-if и v-else для включения и выключения функций CRUD. Первая функция, которую мы собираемся реализовать, — это то, что происходит, если пользователь хочет отредактировать задание.

Используя шаблон, который мы создали в предыдущем примере, мы изменим определение каждой таблицы, чтобы добавить v-if, воздействующее на поле ввода модели, как показано во фрагменте кода, указанном ниже:

<td>
    <input v-if="job.editing" v-model="job.reference" class="form-control">
    </input>
    <span v-else>
        {{ job.reference }}
    </span>

</td>

Повторите это для каждого поля работы, исключая job.id по очевидным причинам.

Убедитесь, что ваш код похож на приведенный ниже фрагмент кода:

<template id="template-job-raw">

    <tr>
        <td>
            {{job.id}}
        </td>
        <td>
            <input v-if="job.editing" v-model="job.reference" class="form-control">
            </input>
            <span v-else>
                {{ job.reference }}
            </span>

        </td>
        <td>
            <input v-if="job.editing" v-model="job.title" class="form-control">
            </input>
            <span v-else>
                 {{ job.title }}
            </span>
        </td>
        <td>
            <input v-if="job.editing" v-model="job.type" class="form-control">
            </input>
            <span v-else>
                {{ job.type }}
            </span>
        </td>
        <td>
            <input v-if="job.editing" v-model="job.description" class="form-control">
            </input>
            <span v-else>
                {{ job.description }}
            </span>
        </td>
        <td>
            <input v-if="job.editing" v-model="job.location" class="form-control">
            </input>
            <span v-else>
               {{ job.location }}
            </span>

        </td>
        <td>
            <input v-if="job.editing" v-model="job.employer" class="form-control">
            </input>
            <span v-else>
                {{ job.employer }}
            </span>
        </td>
        <td>
            <input v-if="job.editing" v-model="job.salary" class="form-control">
            </input>
            <span v-else>
                {{ job.salary }}
            </span>
        </td>
        <td>
            {{ job.post_date }}
        </td>
  </tr>
</template>
<!-- /#template-job-raw -->

Мы успешно добавили нашу логику для создания условия if/else в наше представление, следующий шаг — подумать о том, как мы активируем эту логику для изменения каждого задания?

Ответ заключается в том, что нам нужно добавить кнопки редактирования и удаления в наш код, чтобы наши операторы if else работали, когда пользователь нажимает кнопки.

Вернитесь к шаблону и сразу под последним определением таблицы создайте новое определение таблицы и добавьте следующие кнопки:

<td>
    <div class="btn-group" v-if="!job.editing">
           <button @click="editJob(job)" class="btn btn-default">Edit</button>
           <button @click="deleteJob(job)" class="btn btn-danger">Delete</button>
     </div>
</td>

Нам нужно подумать о том, как наше приложение вызывается с использованием уменьшенной перспективы.

Давайте рассмотрим это, мы создали наше представление, и теперь нам нужно создать файл js, который запустит скрипт для вызова нашего представления.

В общедоступном каталоге создайте новую папку с именем app.js, войдите в эту папку. Давайте создадим компонент vue, так как это полезный способ расширения нашего HTML для инкапсуляции повторно используемого кода.

Добавьте следующий код в app.js

Vue.component('job', {
    template: '#template-job-raw',
    props: ['job'],
    methods: {
        storeJob: function (job) {
            this.$http.post('/api/jobs/', job).then(function (response) {

                Vue.set(job, 'id', response.data.id);

                
                job.editing = false;
            });
        },
    }

});

Мы создали метод storeJob и отправляем POST-запрос к API, созданному в первой части руководства.

Задание сохраняется в серверной части, устанавливается ответ, и мы устанавливаем флаг job.editing в значение false.

Нам нужно инициализировать наш объект vue и создать метод, который будет получать список заданий из базы данных как часть готовой функции.

Добавьте следующий код в файл app.js под замыканием компонента vue.

new Vue({
    el: '#v-app',
    data: {
        jobs: [],
    },
    ready: function () {
        this.fetchJobs()
    },
    methods: {
        fetchJobs: function () {
            var vm = this;
            this.$http.get('/api/jobs')
                .then(function (response) {
                    // set data on vm
                    var jobsReady = response.data.map(function (job) {
                        job.editing = false;
                        return job
                    })
                    vm.$set('jobs', jobsReady)
                });
        }
    }

});

Мы успешно создали методы для получения наших списков вакансий и для хранения вакансий.

Следующим этапом является создание методов для редактирования и обновления наших заданий, чтобы наши кнопки могли работать во внешнем интерфейсе.

Нам нужно добавить следующие методы в наш скрипт app.js editJobs и updateJobs. editJobs установит для флага редактирования задания значение true, в то время как updateJob отправит запрос на исправление, содержащий job.id, в API.

Вернитесь к app.js и внутри компонента vue под методами добавьте методы editJob и updateJob, чтобы он напоминал код, указанный ниже:

editJob: function (job) {
    job.editing = true;
},
updatejob: function (job) {
    this.$http.patch('/api/jobs/' + job.id, job)
    
    job.editing = false;
},

Компонент vue будет выглядеть следующим образом:

Vue.component('job', {
    template: '#template-job-raw',
    props: ['job'],
    methods: {
            editJob: function (job) {
            job.editing = true;
    },
            updatejob: function (job) {
            this.$http.patch('/api/jobs/' + job.id, job)
    
            job.editing = false;
   },
        storeJob: function (job) {
            this.$http.post('/api/jobs/', job).then(function (response) {

                Vue.set(job, 'id', response.data.id);

                
                job.editing = false;
            });
        },
    }

});

Нам нужно вернуться к представлению, в этом случае jobs.html есть 3 кнопки, которые мы еще не добавили. Нам нужно добавить условие v-else в область кнопок, чтобы обновить задание, сохранить задание или отменить редактирование задания. Эти кнопки вызываются только в том случае, если идентификатор задания извлекается из базы данных.

вакансии.html

Под

td>
    {{ job.post_date }}
</td>

Измените код, чтобы добавить вышеупомянутые кнопки, чтобы он напоминал код, указанный ниже:

<td>
    <div class="btn-group" v-if="!job.editing">
        <button @click="editJob(job)" class="btn btn-default">Edit</button>
        <button @click="deleteJob(job)" class="btn btn-danger">Delete</button>
    </div>

    <div class="btn-group" v-else>
        <!--If the job is retrieved from the db then it will have an id-->
        <button v-if="job.id" class="btn btn-primary" @click="updateJob(job)">Update Job
        </button>
        <button v-else class="btn btn-success" @click="storeJob(job)">
            Save New Job
        </button>
        <!-- /.btn -->
        <button @click="job.editing=false" class="btn btn-default">Cancel</button>
    </div>

</td>

Кнопка отмены задания вызовет метод deleteJob, который мы собираемся создать в компоненте vue.

Вернитесь к app.js и добавьте следующий код в качестве первого метода в компоненте vue.

deleteJob: function (job) {
    this.$parent.jobs.$remove(job)
    this.$http.delete('/api/jobs/' + job.id)
},

Готовый компонент vue будет выглядеть так:

Vue.component('job', {
    template: '#template-job-raw',
    props: ['job'],
    methods: {
        deleteJob: function (job) {
            this.$parent.jobs.$remove(job)
            this.$http.delete('/api/jobs/' + job.id)
        },
        editJob: function (job) {
            job.editing = true;
        },
        updatejob: function (job) {
            this.$http.patch('/api/jobs/' + job.id, job)
            //Set editing to false to show actions again and hide the inputs
            job.editing = false;
        },
        storeJob: function (job) {
            this.$http.post('/api/jobs/', job).then(function (response) {
                Vue.set(job, 'id', response.data.id);

                //Set editing to false to show actions again and hide the inputs
                job.editing = false;
            });
        },
    }
})

Вернитесь в браузер и введите jobboard.dev/jobs.html. Обратите внимание, что появится список вакансий, подобный приведенному ниже изображению:

На этом завершается вторая часть нашего руководства, в которой рассказывается, как создать внешний интерфейс с помощью vuejs.

Как разработчик программного обеспечения, специализирующийся на PHP, Laravel и Wordpress, я хотел бы порекомендовать вам посетить мой веб-сайт по адресу www.ormrepo.co.uk.