В первой части руководства мы узнали, как построить нашу серверную архитектуру с использованием 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.