In August 2020, we released a new separate QuickAdminPanel version that generates Vue.js + Laravel API code.
Notice: this version is available only for the Yearly Plan customers.
Compared to the "classic" generator version with jQuery Datatables, this Vue+Laravel code is totally different.
It's a SPA with a front-end-first approach, where most of the logic is inside Vue, using Vue Components, Vue Router, Vuex. Laravel serves only as an API layer, powered by Laravel Sanctum authentication.
Here are a few screenshots of a simple adminpanel, fully generated without writing a single line of code.
As mentioned above, most of the logic of generated panel is inside of Vue.js SPA application.
That said, the public non-auth part of the website is simple Laravel + Blade, without Vue.js at all, the SPA behavior starts only when you log into the panel.
So, inside of the main Blade file resources/views/layouts/admin/app.blade.php you will find this line:
<div id="app"></div>
And from there, everything happens with Vue, in the folder resources/adminapp/js
Here's the code of the main resources/adminapp/js/app.js:
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap')
window.Vue = require('vue')
window.moment.updateLocale('en', { week: { dow: 1 } })
Vue.config.productionTip = false
Vue.prototype.$jquery = $
import App from './App.vue'
// Core
import router from './routes/routes'
import store from './store/store'
import i18n from './i18n'
// Plugins
import GlobalComponents from './globalComponents'
import GlobalDirectives from './globalDirectives'
import GlobalMixins from './mixins/global'
import { mapGetters, mapActions } from 'vuex'
Vue.use(GlobalComponents)
Vue.use(GlobalDirectives)
Vue.use(GlobalMixins)
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
const app = new Vue({
el: '#app',
render: h => h(App),
router,
store,
i18n,
created() {
this.fetchLanguages()
},
methods: {
...mapActions('I18NStore', ['fetchLanguages'])
}
})
Then, all the generated CRUDs are registered as Routes, in resources/adminapp/js/routes/routes.js:
For the Datatables, we're using the Vue2-Datatable package, which we forked under our own LaravelDaily name, to be able to have more control or fixes if needed.
You can see the contents of all other Vue files by checking out the demo repository.
Laravel API Structure
On the back-end, in Laravel, we generate the API routes and Controllers.
And here's an example API Controller, in app/Http/Controllers/Api/V1/Admin/TransactionsApiController.php:
<?php
namespace App\Http\Controllers\Api\V1\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreTransactionRequest;
use App\Http\Requests\UpdateTransactionRequest;
use App\Http\Resources\Admin\TransactionResource;
use App\Models\Transaction;
use Gate;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class TransactionsApiController extends Controller
{
public function index()
{
abort_if(Gate::denies('transaction_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
return new TransactionResource(Transaction::advancedFilter());
}
public function store(StoreTransactionRequest $request)
{
$transaction = Transaction::create($request->validated());
return (new TransactionResource($transaction))
->response()
->setStatusCode(Response::HTTP_CREATED);
}
public function create(Transaction $transaction)
{
abort_if(Gate::denies('transaction_create'), Response::HTTP_FORBIDDEN, '403 Forbidden');
return response([
'meta' => [],
]);
}
public function show(Transaction $transaction)
{
abort_if(Gate::denies('transaction_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');
return new TransactionResource($transaction);
}
public function update(UpdateTransactionRequest $request, Transaction $transaction)
{
$transaction->update($request->validated());
return (new TransactionResource($transaction))
->response()
->setStatusCode(Response::HTTP_ACCEPTED);
}
public function edit(Transaction $transaction)
{
abort_if(Gate::denies('transaction_edit'), Response::HTTP_FORBIDDEN, '403 Forbidden');
return response([
'data' => new TransactionResource($transaction),
'meta' => [],
]);
}
public function destroy(Transaction $transaction)
{
abort_if(Gate::denies('transaction_delete'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$transaction->delete();
return response(null, Response::HTTP_NO_CONTENT);
}
}
We also generate Laravel API Resources, so it would be easier to customize in the future, but they contain mostly default Laravel code. Example from app/Http/Resources/Admin/TransactionResource.php:
<?php
namespace App\Http\Resources\Admin;
use Illuminate\Http\Resources\Json\JsonResource;
class TransactionResource extends JsonResource
{
public function toArray($request)
{
return parent::toArray($request);
}
}
As mentioned above, Authorization is powered by Laravel Sanctum, and for Roles and Permissions on the front-end, we use CASL Vue package, see video demo below: