Laravel Dcat-admin 详情页多栏布局开发

简介: Laravel Dcat-admin 详情页多栏布局开发

背景



随着 dcat-admin 越来越多的人使用,相信有许多跟我一样热爱这个项目的的人最后也会参与到这个项目中来,从使用者到项目的维护者,可以为项目贡献一份自己的力量。我以后也会将维护这个项目的一些心得,底层代码的实现都以博文的形式分享给大家。


需求



有个同学提了一个这样的需求 ; 需要在表单 / 详情支持多栏布局,而这个需求刚好我自己用 dcat-admin 做项目时候也遇到过。尤其是 form 表单字段比较多的时候,我开始的解决方案是通过 form 的 tab 来减少表单一页的字段数量。


表单的多栏目布局


思路:我想的是 form 表单的字段外面包一次 row ,然后控制 row 里面每个字段的长宽。当我看了 dcat-admin 的代码后,发现是已经实现好了的,所以不需要自己在开发,我这里主要讲讲表单的多栏目布局的用法和底层代码怎么实现的。

效果:


image.png


使用代码:


在控制器创建一个 from 方法


protected function form()
  {
      return Form::make(new WxyMaterialItem(), function (Form $form) {
          $form->row(function (Form\Row $row) {
              $row->width(4)->text('name')->required();
              $row->width(4)->text('id');
              $row->width(4)->text('simple_code');
          });
          $form->row(function (Form\Row $row) {
              $row->width(6)->text('integral_money');
              $row->width(6)->text('stock_min');
          });
          $form->row(function (Form\Row $row) {
              $row->width(12)->text('attribute');
          });
          $form->row(function (Form\Row $row) {
              $row->width(3)->text('price1');
              $row->width(3)->text('price2');
              $row->width(3)->text('price3');
              $row->width(3)->text('status');
          });
      });
  }


代码分析:


整个 form 表单渲染出来的流程如下

Dcat\Admin\Form 对象 -> 方法 rows 实例化一个 Dcat\Admin\Form\Row 对象并保存对象属性 -> 最后通过 render 方法渲染界面


这里面核心作用文件是 Dcat\Admin\Form\Row,我们可以看看里面的几个方法


width 方法


public function width($width = 12)
  {
      $this->defaultFieldWidth = $width;
      return $this;
  }


这个方法主要设置当前行的每一个显示字段的宽度,比如你一行显示三个字段

建议每个字段的宽度设置为 3,例如 $row->width (3)->text (‘name’);


__call 方法


public function __call($method, $arguments)
  {
      $field = $this->form->__call($method, $arguments);
      $field->disableHorizontal();
      $this->fields[] = [
          'width'   => $this->defaultFieldWidth,
          'element' => $field,
      ];
      return $field;
  }


这个方法主要是保存当前行要显示的字段的信息,通过 __call 方法去调用 Dcat\Admin\Form 的字段方法获取字段信息,如使用代码的 $row->width (4)->text (‘name’),会保存一个宽度 col-md-4 的 Dcat\Admin\Form\Field\Text 字段。


render 方法


public function render()
  {
      return view('admin::form.row', ['fields' => $this->fields]);
  }


admin::form.row 视图


<div class="row">
  @foreach($fields as $field)
  <div class="col-md-{{ $field['width'] }}">
      {!! $field['element']->render() !!}
  </div>
  @endforeach
</div>


$field [‘element’]->render () 就是将字段渲染成 html

我们可以 dd 下 $this->fields , 看看其数据结构


详情的多栏目布局



思路:详情的多栏目布局是需要重新开发的,思路逻辑是和表单的多栏目布局类似的

主要是创建一个 Dcat\Admin\Show\Row 文件,里面的代码如下


<?php
namespace Dcat\Admin\Show;
use Dcat\Admin\Show;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Support\Collection;
class Row implements Renderable
{
    /**
     * Callback for add field to current row.s.
     *
     * @var \Closure
     */
    protected $callback;
    /**
     * Parent show.
     *
     * @var Show
     */
    protected $show;
    /**
     * @var Collection
     */
    protected $fields;
    /**
     * Default field width for appended field.
     *
     * @var int
     */
    protected $defaultFieldWidth = 12;
    /**
     * Row constructor.
     *
     * @param \Closure $callback
     * @param Show $show
     */
    public function __construct(\Closure $callback, Show $show)
    {
        $this->callback = $callback;
        $this->show = $show;
        $this->fields = new Collection();
        call_user_func($this->callback, $this);
    }
    /**
     * Render the row.
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function render()
    {
        return view('admin::show.row', ['fields' => $this->fields]);
    }
    /**
     * @return Collection|\Dcat\Admin\Show\Field[]
     */
    public function fields()
    {
        return $this->fields;
    }
    /**
     * Set width for a incomming field.
     *
     * @param int $width
     *
     * @return $this
     */
    public function width($width = 12)
    {
        $this->defaultFieldWidth = $width;
        return $this;
    }
    /**
     * Add field.
     *
     * @param string $name
     * @param string $label
     *
     * @return \Dcat\Admin\Show\Field
     */
    public function field($name, $label = '')
    {
        $field = $this->show->field($name, $label);
        $this->pushField($field);
        return $field;
    }
    /**
     * Add field.
     *
     * @param $name
     *
     * @return \Dcat\Admin\Show\Field|Collection
     */
    public function __get($name)
    {
        $field = $this->show->field($name);
        $this->pushField($field);
        return $field;
    }
    /**
     * @param $method
     * @param $arguments
     *
     * @return \Dcat\Admin\Show\Field
     */
    public function __call($method, $arguments)
    {
        $field = $this->show->__call($method, $arguments);
        $this->pushField($field);
        return $field;
    }
    /**
     * @param \Dcat\Admin\Show\Field $field
     *
     * @return void
     */
    protected function pushField($field)
    {
        $this->fields->push([
            'width'   => $this->defaultFieldWidth,
            'element' => $field,
        ]);
    }
}


里面 __ cal l, __get , field 三个方法都是获取当前行的字段信息,并保存到行的属性,在最后渲染详情的时候先循环 rows(这一步在 Dcat\Admin\Show\Panel 的 render 方法), 在通过上面代码中的 render 方法渲染 rows 的每个字段;如下:


html 如下


<div class="box-body">
  <div class="form-horizontal mt-1">
      @if($rows->isEmpty())
          @foreach($fields as $field)
              {!! $field->render() !!}
          @endforeach
      @else
          <div>
              @foreach($rows as $row)
                  {!! $row->render() !!}
              @endforeach
          </div>
      @endif
      <div class="clearfix"></div>
  </div>
</div>


使用代码:


控制器创建一个 detail 方法


protected function detail($id)
  {
      return Show::make($id, new WxyMaterialItem("brands"), function (Show $show) {
          $show->row(function (Show\Row $row) {
              $row->width(6)->name;
              $row->width(6)->simple_code;
          });
          $show->row(function (Show\Row $row) {
              $row->width(4)->specs;
              $row->width(4)->integral_money;
              $row->width(4)->field("aa", "你好");
          });
          $show->row(function (Show\Row $row) {
              $row->width(4)->mdept_id("部门");
              $row->width(4)->status;
              $row->width(4)->field("brands.name", "品牌");
          });
      });
  }


 


目录
相关文章
|
2月前
|
JavaScript 容器
vue-element-admin 综合开发二:搭建首页架子、侧边栏、修改默认样式、menu和路由跳转页面初体验
这篇文章详细介绍了如何使用Vue和Element UI搭建一个后台管理系统,包括首页布局、侧边栏、样式调整、菜单和路由配置,以及解决开发中遇到的问题。
176 1
vue-element-admin 综合开发二:搭建首页架子、侧边栏、修改默认样式、menu和路由跳转页面初体验
|
4月前
|
前端开发
炫酷登录页大变身:5分钟带你入门Web动效设计
炫酷登录页大变身:5分钟带你入门Web动效设计
|
5月前
|
小程序 开发工具 开发者
【微信小程序-原生开发】实用教程02-添加全局页面配置、页面、底部导航
【微信小程序-原生开发】实用教程02-添加全局页面配置、页面、底部导航
71 0
|
5月前
|
前端开发
uniapp 实战 -- 创建 uni-admin 项目,部署到 uniCloud 前端网页托管(免费云空间)
uniapp 实战 -- 创建 uni-admin 项目,部署到 uniCloud 前端网页托管(免费云空间)
414 0
|
5月前
|
JSON 小程序 JavaScript
【微信小程序-原生开发】TDesign 实战模板——账号密码登录页(含密码显示隐藏的技巧)
【微信小程序-原生开发】TDesign 实战模板——账号密码登录页(含密码显示隐藏的技巧)
160 0
|
缓存 前端开发 NoSQL
vue-element-admin实战 | 第二篇: 最小改动接入后台实现根据权限动态加载菜单
vue-element-admin实战 | 第二篇: 最小改动接入后台实现根据权限动态加载菜单
|
JSON 小程序 前端开发
小程序搭建OA项目首页布局界面
小程序搭建OA项目首页布局界面
102 0
Bootstrap03购物车页面&登录注册界面&其他组件使用
Bootstrap03购物车页面&登录注册界面&其他组件使用
163 0
|
前端开发
关于vue-admin-work后台前端管理框架重大升级
前段时间我们发布了 vue-admin-work的初期版本,受到了很多的小伙伴的支持与鼓励,在这里再次感谢大家对 vue-admin-work的关注。但是在此期间我们也发现了很多的不足之处
关于vue-admin-work后台前端管理框架重大升级
|
JavaScript 前端开发 计算机视觉
【Vue3从零开始-实战】S15:详情页tab栏核心样式开发
【Vue3从零开始-实战】S15:详情页tab栏核心样式开发
371 0
【Vue3从零开始-实战】S15:详情页tab栏核心样式开发