Можно ли использовать основные методы laravel из компонента Vue.js?

Мне относительно комфортно с Laravel 5, но я довольно зеленый, когда дело доходит до Vue.js, и я блуждал, можно ли вызывать методы Laravel, доступные из лезвия, в компоненте Vue.js.

Например, я хочу создать компонент Vue.js для своей панели навигации следующим образом:

<template>
    <nav class="navbar navbar-expand-sm navbar-dark bg-info mb-2">
        <div class="container">
            <a href="{{ route('home') }}" class="navbar-brand">Go Home</a>
        </div>
    </nav>
</template>

<script>
    export default {
        name: "NavBar"
    }
</script>

home — это именованный маршрут в моем файле wep.php

Route::get('/', 'SiteController@index')
    ->name('home');

и я добавил свой компонент Vue следующим образом:

Vue.component('navbar', require('./components/NavBar'));

в моем файле app.js

Как я могу сделать что-то подобное? В этом примере я использую метод route() только для вставки тега src, но мне также интересно сделать что-то аналогичное этому из компонента Vue.js.

@if (Route::has('login'))
    <div class="top-right links">
        @auth
           <a href="{{ url('/home') }}">Home</a>
        @else
           <a href="{{ route('login') }}">Login</a>
           <a href="{{ route('register') }}">Register</a>
        @endauth
    </div>
@endif

Вот как я бы сделал это из моего файла *.blade.php, но как я могу реализовать подобную логику, используя компоненты Vue? Кстати, я использую Laravel 5.7.


person natral    schedule 08.11.2018    source источник
comment
Вы можете использовать встроенные шаблоны, но я считаю плохой практикой смешивать PHP с вашими компонентами. При необходимости вы можете передать реквизиты своим компонентам из шаблона блейда.   -  person Devon    schedule 08.11.2018
comment
Как я уже сказал @Devon, я новичок в Vue.js, у вас есть ссылки на документацию по этому вопросу, которую я могу посмотреть. Спасибо   -  person natral    schedule 08.11.2018
comment
Реквизиты — довольно важная часть Vue. Вы спрашиваете о документации для реквизита?   -  person Devon    schedule 08.11.2018
comment
Что касается маршрута, есть пакет, который может оказаться полезным: github.com/tightenco/ziggy. создать метод глобального маршрута в javascript.   -  person Noogen    schedule 13.11.2018


Ответы (1)


Я создавал приложения Vue с Laravel без каких-либо шаблонов лезвий, кроме индекса, чтобы представить базовые метаданные HTML, необходимые для запуска SPA.

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

Чтобы начать работу и заполнить Vue всеми доступными веб-маршрутами, добавьте следующее в routes/web.php.

Route::get('/js/routes.js', function() {

    // White list namespaces that can be exposed to Vue.
    $allow = ['App\Http\Controllers'];

    // uncomment below to enable cache
    // $routes = \Illuminate\Support\Facades\Cache::rememberForever('routes.js', function () {

        $routes = [];

        foreach(Route::getRoutes()->getIterator() AS $route)
        {
            if(!array_key_exists('namespace',$route->action))
                continue;

            if(!is_array($route->action['middleware']))
                continue;

            if(in_array($route->action['namespace'],$allow,true))
                continue;

            $name = $route->getName();

            if(empty($name))
                continue;

            $routes[$name] = $route->uri;
        };

        return $routes;


    // });

    header('Content-Type: text/javascript');
    echo 'let routes = ' . json_encode($routes) . ';';
    echo 'window.route = function() { let args = Array.prototype.slice.call(arguments); let name = args.shift();if(routes[name] === undefined) { console.error(\'Unknown route \', name); } else { return \'/\' + routes[name].split(\'/\').map(s => s[0] == \'{\' ? args.shift() : s).join(\'/\');}};';
    exit();

})->name('assets.routes');

Добавьте в файл макета блейда:

<link rel="preload" href="/js/routes.js" as="script">

Чтобы затем сделать эти маршруты доступными в компонентах Vue, вы можете выполнить привязку к Vue, используя следующий пример после импорта Vue из 'Vue':

Vue.prototype.$getRoute = window.route;
Vue['getRoute'] = window.route;

Затем вы можете в методах Vue использовать this.getRoute('laravels.route.name', [ id: user.id ]), это работает так же, как функция route в Laravel с переменными URL, передаваемыми в качестве второго параметра. В компоненте ссылки маршрутизатора или в событии клика это будет работать так:

<router-link :to="$getRoute('logout')">Logout</router-link>

<button @click="$getRoute('logout')">Logout</button>

Значение, переданное в getRoute, — это имя маршрута в Laravel, когда вы используете Route::get(...)->name('my.custom.route.name') в web.php.

Используйте команду php artisan route:list, чтобы перечислить все имена маршрутов созданных вами ресурсов, которые вы можете использовать для $getRoute() в Vue.


В качестве дополнительного бонуса вы можете вернуть пользовательские данные JSON для нового пользователя, прошедшего проверку подлинности, отредактировав Auth/LoginController.php и добавив следующий метод:

 public function authenticated(Request $request, $user)
 {
    return response()->json([
        'redirect' => session()->pull('url.intended')
    ]);
 }

Вы можете расширить это и вернуть много дополнительных учетных данных. Для начала я возвращаю предполагаемый путь перенаправления, который на самом деле принадлежит маршрутизатору Vue. Приложение Vue уже подтолкнуло пользователя к экрану входа в систему, но у Laravel также есть моментальный снимок сеанса, где пользователь шел до того, как произошло this.$router.push('login').

Vue.prototype.$Laravel = window.Laravel;
Vue['Laravel'] = window.Laravel;

logMeIn() {

    this.$root.isAuthenticating = true;

    axios.post(this.$getRoute('login.send'),this.input).then(response => {

        this.Laravel.myArray = response.data.myArray;

        this.$router.push(response.data.redirect);

    }).catch(error => {

        this.$root.isAuthenticating = false;
        ErrorHandler(this,error);

    });

},
person Marc    schedule 08.11.2018