一、介绍
有时候,我们需要实现一些表自关联的菜单效果,比如类目(Category )管理等,laravel-admin能够帮助我们快速,创建树形效果菜单。laravel-admin有丰富的组件库,其底层是基于boostrap封装的,因此基本组件没有的可以自己定义实现。查看了laravel-admin的官方文档,使用介绍也非常详细,基本上一分钟即可搭建一个高可用的基础后台管理系统。结合php和laravel,三者都是在提速增效。做全栈快速应对业务变化,做一些小程序、公众号、cms的开发,简直就是神速。官网https://laravel-admin.org/
-
默认系统自带效果如下。今天就是自定义实现这个效果。
image.png
-
实现参考文档
image.png
二、实现步骤
- 创建表迁移文件
php artisan make:migration create_menus_table
在生成的迁移文件中,添加以下代码:
![](https://img.haomeiwen.com/i5287237/b8149b9f09b17ac1.png)
Schema::create('menus', function (Blueprint $table) {
$table->comment('菜单表');
$table->id()->comment('主键');
$table->bigInteger('pid')->comment('父ID');
$table->integer('order')->comment('排序');
$table->string('title')->unique()->comment('名称');
$table->string('icon',64)->comment('图标');
$table->string('uri')->comment('路径');
$table->timestamps();
});
- 执行迁移命令
php artisan migrate
即可生成如下表:
CREATE TABLE `menus` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`pid` bigint(20) NOT NULL COMMENT '父ID',
`order` int(11) NOT NULL COMMENT '排序',
`title` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '名称',
`icon` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '图标',
`uri` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '路径',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `menus_title_unique` (`title`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='菜单表';
- 生成菜单模型
php artisan make:model Menu
执行生成前,需要正确安装好了laravel-admin,其安装此处省略。
<?php
namespace App\Models;
use App\Helpers\core\SerializeDate;
use Encore\Admin\Traits\ModelTree;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Menu extends Model
{
use HasFactory;
use SerializeDate;
use ModelTree;
protected $fillable = ['pid', 'order', 'title', 'icon', 'uri'];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->setParentColumn('pid'); // 父ID
$this->setOrderColumn('order'); // 排序
$this->setTitleColumn('title'); // 标题
}
}
其中关键代码:
use Encore\Admin\Traits\ModelTree;
use ModelTree;
protected $fillable = ['pid', 'order', 'title', 'icon', 'uri'];
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->setParentColumn('pid'); // 父ID
$this->setOrderColumn('order'); // 排序
$this->setTitleColumn('title'); // 标题
}
- 剩下什么都不需要做,直接生成控制器。指定
--model=App\Models\Menu
生成。
php artisan admin:make MenuController --model=App\Models\Menu
清空app/Admin/Controllers/MenuController.php自动生成内容,采用如下代码替换。
<?php
namespace App\Admin\Controllers;
use App\Models\Menu;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Controllers\HasResourceActions;
use Encore\Admin\Form;
use Encore\Admin\Layout\Column;
use Encore\Admin\Layout\Content;
use Encore\Admin\Layout\Row;
use Encore\Admin\Tree;
use Encore\Admin\Widgets\Box;
class MenuController extends AdminController
{
use HasResourceActions;
/**
* Title for current resource.
*
* @var string
*/
protected $title = 'Menu';
public function index(Content $content)
{
return $content
->title('菜单')
->description('菜单描述')
->header('菜单')
->row(function (Row $row) {
$row->column(6, $this->treeView()->render());
$row->column(6, function (Column $column) {
$form = new \Encore\Admin\Widgets\Form();
$form->action(admin_url('menus'));
$form->select('pid', trans('admin.parent_id'))->options(Menu::selectOptions());
$form->text('title', trans('admin.title'))->rules('required');
$form->icon('icon', trans('admin.icon'))->default('fa-bars')->rules('required')->help($this->iconHelp());
$form->text('uri', trans('admin.uri'));
$form->number('order', trans('admin.order'))->default(99)->help('越小越靠前');
$form->hidden('_token')->default(csrf_token());
$column->append((new Box(trans('admin.new'), $form))->style('success'));
});
});
}
public function show($id, Content $content)
{
return redirect()->route('admin.menus.edit', ['menu' => $id]);
}
protected function treeView()
{
$tree = new Tree(new Menu());
$tree->disableCreate();
$tree->branch(function ($branch) {
$payload = "<i class='fa {$branch['icon']}'></i> <strong>{$branch['title']}</strong>";
if (!isset($branch['children'])) {
if (url()->isValidUrl($branch['uri'])) {
$uri = $branch['uri'];
} else {
$uri = url($branch['uri']);
}
$payload .= " <a href=\"$uri\" class=\"dd-nodrag\">$uri</a>";
}
return $payload;
});
return $tree;
}
public function edit($id, Content $content)
{
return $content
->title(trans('admin.menu'))
->description(trans('admin.edit'))
->row($this->form()->edit($id));
}
public function form()
{
$form = new Form(new Menu());
$form->display('id', 'ID');
$form->select('pid', trans('admin.parent_id'))->options(Menu::selectOptions());
$form->text('title', trans('admin.title'))->rules('required');
$form->icon('icon', trans('admin.icon'))->default('fa-bars')->rules('required')->help($this->iconHelp());
$form->text('uri', trans('admin.uri'));
$form->number('order', trans('admin.order'))->default(99)->help('越小越靠前');
$form->display('created_at', trans('admin.created_at'));
$form->display('updated_at', trans('admin.updated_at'));
return $form;
}
protected function iconHelp()
{
return 'For more icons please see <a href="http://fontawesome.io/icons/" target="_blank">http://fontawesome.io/icons/</a>';
}
}
- 至此,即可实现完成。实现非常简单,参考官网源码即可。
vendor/encore/laravel-admin/src/Controllers/MenuController.php
打开vendor目录,找到控制器目录下的MenuController.php
文件然后复制粘贴即可。 -
记得添加路由
image.png
就一行代码搞定:
$router->resource('menus', \App\Admin\Controllers\MenuController::class);
自动实现了相关路由:
![](https://img.haomeiwen.com/i5287237/6f78e81a76217115.png)
- 细节处理
菜单的编辑页面的查看按钮,自动生成无法隐藏,因此也直接跳转到编辑页面。
image.png
执行php artisan route:list
找到admin/auth/menu/{menu}/edit
路由的别名admin.menus.edit
在show
函数中填写如下即可。
public function show($id, Content $content)
{
return redirect()->route('admin.menus.edit', ['menu' => $id]);
}
添加一个排序字段,测试效果。
$form->number('order', trans('admin.order'))->default(99)->help('越小越靠前');
注意添加csrf隐藏域,目的是为了防止csrf攻击,laravel默认开启了csrf的token。这有别于一般的其他语言的框架,使得使用laravel编写项目,同时安全性也得到保障。
$form->hidden('_token')->default(csrf_token());
三、最终效果
![](https://img.haomeiwen.com/i5287237/df18e382c2fe5cba.png)
- 至此,所有效果均已实现。其它类似效果,参考实现即可。
网友评论