Одна из моих любимых вещей в ((http://vuejs.org/ Vue.js)) - он работает на простейших страницах с простейшими компонентами. Вам не нужны никакие сложные инструменты сборки или деревья зависимостей. Но Vue не ограничивается только простыми компонентами. ((https://github.com/vuejs/vue-resource Vue-resource)) делает AJAX простым, с ((http://vuejs.github.io/vue-router/en/ vue-router)) можно настроить маршрутизацию одностраничного приложения почти без усилий. И я обещаю, когда-нибудь я выучу и ((https://github.com/vuejs/vuex Vuex)). Я хочу показать вам, насколько просто использовать vue-router для создания одностраничного приложения с помощью Vue. И уж поверьте мне - это просто. Если вы уже создавали свой компонент с помощью Vue, то 90% работы позади. == Настройка == Как это часто бывает, в качестве инструмента для сборки я выбрал ((https://laravel.com/docs/elixir Laravel Elixir)). Вы можете использовать любую систему сборки, которая предоставляет вам доступ к вашим NPM-пакетам. Или вы можете включить пакет в сборку вручную (с помощью ((https://cdnjs.cloudflare.com/ajax/libs/vue-router/0.7.10/vue-router.min.js CDN)) ) или с помощью Bower. В итоге вам нужен %%(t)vue-router%%, установленный любым способом. Если вы не собираетесь использовать Elixir, то просто пропустите следующий раздел. === Установка Vue и vue-router с помощью Laravel Elixir (не обязательно) === Если вы собираетесь начать новый проект используя Laravel Elixir, прочтите документацию с инструкциями по базовой установке. Затем добавьте %%(t)vue%% и %%(t)vue-router%%: %%(sh) npm install vue vue-router --save %% Далее вам надо добавить задачу Browserify для вашего JavaScript файла: %%(js) // gulpfile.js elixir(function (mix) { mix.browserify('app.js'); }); %% Теперь ожидается, что у вас есть файл %%(t)resources/assets/js/app.js%%, который будет передаваться через Browserify и Babel и выводиться в %%(t)public/js/app.js%%. Создайте "ресурсную" версию этого файла и выполните %%(sh)gulp watch%%, чтобы запустить его. === Включение зависимостей === Вам надо включить Vue и vue-router в свой основной JavaScript файл с помощью любой доступной вам системы импорта: %%(js) var Vue = require('vue'); var VueRouter = require('vue-router'); Vue.use(VueRouter); %% Мы включили Vue и vue-router, и затем связывали их друг с другом. Теперь давайте напишем наше приложение. == Создание своего приложения == Как в любом Vue-приложении, нам надо создать базовое приложение. Но в отличие от других Vue-приложений, ядро шаблонной работы, которую мы будем делать, это отображение нескольких компонентов по нескольким маршрутам. Во Vue нет такого нового понятия как "страница", каждая страница - это просто компонент, который может содержать другие компоненты. Давайте создадим наше приложение и наш маршрутизатор: %%(js) var App = Vue.extend({}); var router = new VueRouter(); router.start(App, '#app'); %% Вот и всё! Оно не будет ничего делать, потому что мы не отобразили ни одного маршрута, но мы определили приложение, определили маршрутизатор, собрали их воедино, и затем инициализировали маршрутизатор. == Отображение компонентов по маршрутам == У нас есть приложение и маршрутизатор, давайте определим несколько маршрутов: %%(js) var App = Vue.extend({}); var router = new VueRouter(); var Home = Vue.extend({ template: 'Добро пожаловать на главную страницу!' }); var People = Vue.extend({ template: 'Посмотрите на всех, кто тут работает!' }); router.map({ '/': { component: Home }, '/people': { component: People } }); router.start(App, '#app'); %% Мы определили два возможных маршрута в нашем приложении и указали компонент для каждого из них. == Сборка HTML-страницы == Давайте создадим HTML-страницу для размещения нашего маршрутизатора. Этой странице не обязательно быть полностью пустой, как вы могли бы подумать. При использовании vue-router ваше приложение может содержать какой-либо код, и он не будет отключен из-за использования компонентов, например, это может быть панель навигации. %%(html) ...

Our company

... %% Предположим, у этой страницы есть HTML-заголовок и блочные теги, а также она импортирует наши скрипты и зависимости где-нибудь в заголовке или подвале. Здесь мы видим несколько важных вещей. Во-первых, когда мы запустили наш маршрутизатор в скрипте, мы связали его с '#app', поэтому нам надо создать элемент страницы с ID = "app", с которым мы свяжем наше Vue-приложение. Во-вторых, здесь использован Vue-синтаксис для ссылок - используется свойство %%(t)v-link%% и передаётся в JSON-объект. Мы будем делать так: %%(t){ path: '/url-here' }%%. .(alert) Если открываемая в данный момент ссылка "активна" (открыта у пользователя), маршрутизатор применит для неё класс %%(t)v-link-active%%, и вы сможете настроить для неё уникальный стиль. Также вы можете изменить этот класс или применять его для отдельных связанных элементов, таких как родительские %%(t)div%% или %%(t)li%% - вы можете узнать больше из документации. И наконец, у нас есть компонент %%(t)%%, сюда будет приходить вывод каждого компонента. Если вы зайдёте на эту страницу, и всё корректно загрузится, значит вы сделали своё первое одностраничное приложение с помощью vue-router! .(alert) Вы могли заметить, что сейчас в нём используется шебанг-стиль навигации, то есть все ваши маршруты начинаются с %%(t)#!%%. Это можно отключить, мы поговорим об этом позже, но приготовьтесь, потребуется немного танцев с бубном. == Более продвинутое определение маршрута == Выше мы определили несколько довольно простых маршрутов. Давайте копнём немного глубже в направлении типов маршрутов, которые можно определить с помощью vue-router. === Параметры маршрута === Возможно вам понадобится определить более сложные маршруты, чем просто статические URL. Мы будем вызывать URL, которые могут соответствовать нескольким "динамическим" URL. Посмотрим, как определить такой маршрут. %%(js) router.map({ '/people/:personId': { component: { template: 'Person ID is {{$route.params.personId}}' } } }); %% Из этого примера мы можем узнать несколько вещей. Во-первых, мы видим, что vue-router отображает динамические параметры используя такой синтаксис: %%(t):paramName%%. Во-вторых, мы видим, что vue-router позволяет при желании определять объекты компонентов в строку. И в-третьих, мы видим, что у нас есть доступ к объекту %%(t)$route%% со свойством %%(t)params%%, который является объектом всех подходящих параметров динамических URL. ==== Маски сегментов маршрута ==== Когда надо определить сегмент динамического маршрута, который может подходить для нескольких сегментов, используйте в начале имени сегмента **%%(t)*%%** вместо **%%(t):%%** : %%(js) router.map({ '/people/*greedy' => {}, '/people/*greedy/baz' => {}, }); %% Первое определение маршрута будет подходить для %%(t)/people/a%%, %%(t)/people/a/b%%, %%(t)/people/a/b/c/d/e/f%%. Второе определение маршрута будет подходить для %%(t)/people/a/baz%%, %%(t)/people/a/b/c/d/e/f/g/baz%% и т.д. Оба будут возвращать сегмент %%(t)greedy%% по маршруту %%(t)$route.params.greedy%%, что эквивалентно полной строке для этого сегмента. %%(t)/people/a/b/baz%% будет возвращать %%(t){ greedy: 'a/b' }%%. === Именованные маршруты === Если вы когда-либо использовали маршруты Laravel, то вы уже знакомы с идеей - давать любому маршруту "имя", на которое можно ссылаться позже. С vue-router это тоже возможно: %%(js) router.map({ '/people/:personId': { name: 'people.show', component: People } }); %% Далее вы можете ссылаться на этот маршрут с помощью %%(t)v-link%%: %%(html) Person 5 %% === Переход по маршруту в JavaScript === Мы рассмотрели, как %%(t)v-link%% может заменять обычные ссылки, а что если вам надо инициировать событие перехода в вашем JavaScript? Тут вам поможет %%(t)router.go()%%: %%(js) router.go({ name: 'people.show', params: { personId: 5 }}); %% Также вы можете использовать %%(t)router.replace()%%, который работает так же, но при этом не создаёт новой записи в истории браузера. == Настройки маршрутизатора == Когда вы создаёте экземпляр объекта маршрутизатора в начале вашего JavaScript-файла, вы можете передать в него несколько параметров для настройки. * **hashbang** - если задать значение %%(t)false%%, система будет использовать настоящие URL (%%(t)/people%%) вместо шебанга (%%(t)/#!/people%%). Если вы сделаете так, то вам надо будет включить **history** и соответственно настроить свой сервер. * **history** - использует момент отправки в браузере для обновления истории посещений в нём при переходах на сайте. Требует ((http://readystate4.com/2012/05/17/nginx-and-apache-rewrite-to-support-html5-pushstate/ правильной настройки)) вашего сервера. * **root** - если ваше приложение находится не в корне на сервере, то задайте это свойство для указания правильной подпапки, в которой находится приложение. Например, если ваше приложение находится в %%(t)/app%%, то задайте значение %%(t)/app%%, тогда vue-router будет генерировать соответствующие URL - %%(t)/app/people%% вместо %%(t)/people%%. .(alert) Если вы используете это приложение внутри Laravel-приложения, то вместо настройки nginx или Apache для обработки без-шебангового состояния отправки вы можете настроить своё Laravel-приложение для его обработки. Просто установите маршрут для захвата всех валидных URL и передачи их в представление, выводящее ваш Vue-код: %%(js) Route::get('/{vue_capture?}', function () { return view('home'); })->where('vue_capture', '[\/\w\.-]*'); %% == Получение информации маршрута в ваших компонентах == У каждого компонента в вашем приложении будет доступ к %%(t)this.$route%%, который является "контекстным объектом маршрута" и предоставляет свойства, которые могут быть полезны для получения информации о вашем маршруте. У ваших шаблонов тоже будет доступ к этому объекту через %%(t)$route%%. * %%(t)$route.path%% эквивалентен абсолютному пути, например, %%(t)/people%% * %%(t)$route.params%% содержит пары ключ/значение ваших динамических разделов, например, %%(t){ personId: 5 }%% * %%(t)$route.query%% содержит пары ключ/значение вашей строки запроса, например, %%(t)/people?sortBy=names%% будет возвращать %%(t){ sortBy : lastName }%% * %%(t)$route.router%% возвращает экземпляр vue-router * %%(t)$route.matched%% возвращает объекты конфигурации маршрута для каждого подходящего сегмента в текущем маршруте * %%(t)$route.name%% возвращает имя текущего маршрута, если таковое имеется Вы также можете передать в свои компоненты произвольные данные, передав их в определение маршрута. Например, я хочу, чтобы некоторые секции моего приложения были доступны только администратору, тогда я передаю это в виде флага в определение маршрута, а внутри компонента проверю его наличие как %%(t)$route.adminOnly%%. %%(js) router.map({ '/secret-admin-panels': { component: SecretDashboard, adminOnly: true } }); %% == Настройка хуков == Я мог бы проверять свойство %%(t)$route.adminOnly%% в своих компонентах, но ещё лучше, если это будет обработано до того, как пользователь получит доступ к компоненту, при помощи посредника. При использовании vue-router это будут хуки маршрута, такие как %%(t)beforeEach%%: %%(js) // Пример проверки доступа пользователя var MyUser = { admin: false }; router.beforeEach(function (transition) { if (transition.to.adminOnly && ! MyUser.admin) { transition.redirect('/login'); } else { transition.next(); } }); %% Как видите, мы перехватываем запрос //перед// отрисовкой компонента. Мы можем разрешить дальнейший переход с помощью %%(t)transition.next()%%, а также мы можем перехватить пользователя и перенаправить или отменить переход - %%(t)transition.abort()%%. Существует также хук %%(t)afterEach()%%. == Разное == Ещё несколько последних замечаний. Первое, %%(t)%% может быть передан точно так же, как и любой другой страничный компонент. Второе, для Vue есть полное ((http://vuejs.github.io/vue-router/en/pipeline/index.html описание переходов)), которое можно использовать для определения визуального и функционального поведения при переходах между страницами. Третье, эта статья охватывает далеко не всё, загляните в ((http://vuejs.github.io/vue-router/en/ документацию)). == Заключение == Вот теперь всё. Вы увидели насколько просто настроить своё первое одностраничное приложение при помощи Vue и vue-router, и насколько плавный переход от единственного компонента к одностраничному приложению. Если хотите посмотреть на (какой-нибудь) работающий пример использования vue-router, то можете взглянуть на обучающее приложение ((http://github.com/mattstauffer/suggestive Suggestive)), над которым я сейчас работаю.