dcat-admin

dcat-admin


异步加载基本使用

<h1>异步加载基本使用</h1> <p>&gt; {tip} 异步加载功能支持<strong>静态资源按需加载</strong>的特性,目前内置的<strong>所有组件</strong>都支持使用异步渲染功能,并且支持在页面的<strong>任意位置</strong>中使用</p> <p>通过异步加载功能可以让页面中的整体或局部组件使用<code>ajax</code>异步渲染,从而提高页面加载效率(例如弹窗异步加载表单)。</p> <h2>基本用法</h2> <p>下面通过一个简单的示例来演示异步加载功能的用法</p> <p>先定义一个异步渲染类,继承<code>Dcat\Admin\Support\LazyRenderable</code></p> <pre><code class="language-php">&amp;lt;?php namespace App\Admin\Renderable; use App\Admin\Widgets\Charts\Bar; use Dcat\Admin\Support\LazyRenderable; class PostChart extends LazyRenderable { public function render() { // 获取外部传递的参数 $id = $this-&amp;gt;id; // 查询数据逻辑 $data = [...]; // 这里可以返回内置组件,也可以返回视图文件或HTML字符串 return Bar::make($data); } }</code></pre> <p>然后需要把渲染类实例传入<code>Dcat\Admin\Widgets\Lazy</code>对象中,才能最终实现异步渲染的效果</p> <pre><code class="language-php">use App\Admin\Renderable\PostChart; use Dcat\Admin\Widgets\Lazy; use Dcat\Admin\Layout\Content; public function index(Content $content) { // 实例化异步渲染类并传递自定义参数 $chart = PostChart::make(['id' =&amp;gt; ...]); return $content-&amp;gt;body(Lazy::make($chart)); }</code></pre> <p>也可以放在内置组件中</p> <p>&gt; {tip} 如果是 <code>Dcat\Admin\Widgets\Card</code>、<code>Dcat\Admin\Widgets\Box</code>、<code>Dcat\Admin\Widgets\Modal</code>、<code>Dcat\Admin\Widgets\Tab</code>等组件,则可以略过<code>Dcat\Admin\Widgets\Lazy</code>组件,直接传递渲染类实例</p> <pre><code class="language-php">use App\Admin\Renderable\PostChart; use Dcat\Admin\Widgets\Card; use Dcat\Admin\Layout\Content; public function index(Content $content) { $chart = PostChart::make(['id' =&amp;gt; ...]); // Card 组件支持直接传递 LazyRenderable 实例,可以略过 Lazy 对象 return $content-&amp;gt;body(Card::make($chart)); } // 如果是 Modal、Box 等等都可以直接略过 Lazy use Dcat\Admin\Widgets\Modal; $chart = PostChart::make(['id' =&amp;gt; ...]); $modal = Modal::make() -&amp;gt;lg() -&amp;gt;title('标题') -&amp;gt;delay(300) // 如果是异步渲染图表则需要设置一个延迟时间,否则可能导致图表渲染异常 -&amp;gt;body($chart);</code></pre> <p>当然也可以防止在视图或者是<code>HTML</code>代码中</p> <pre><code class="language-php">use App\Admin\Renderable\PostChart; use Dcat\Admin\Widgets\Lazy; use Dcat\Admin\Layout\Content; public function index(Content $content) { $chart = Lazy::make(PostChart::make(['id' =&amp;gt; ...])); return $content-&amp;gt;body(view('admin.xxx', ['chart' =&amp;gt; $chart])); }</code></pre> <p>效果</p> <p>&lt;a href=&quot;<a href="https://cdn.learnku.com/uploads/images/202008/20/38389/Z1X46kZLtM.gif!large&quot">https://cdn.learnku.com/uploads/images/202008/20/38389/Z1X46kZLtM.gif!large&quot</a>; target=&quot;_blank&quot;&gt; <img src="https://cdn.learnku.com/uploads/images/202008/20/38389/Z1X46kZLtM.gif!large" alt="" /> &lt;/a&gt;</p> <h3>Dcat\Admin\Support\LazyRenderable</h3> <h4>参数传递 (payload)</h4> <pre><code class="language-php">use App\Admin\Renderable\PostChart; PostChart::make(['key1' =&amp;gt; '值', ...]); // 也可以通过 payload 方法传递 PostChart::make()-&amp;gt;payload(['key1' =&amp;gt; '值', ...]);</code></pre> <p>获取参数</p> <pre><code class="language-php">class PostChart extends LazyRenderable { protected $title = ['#', '标题', '内容']; public function render() { // 获取外部传递的参数 $key1 = $this-&amp;gt;key1; $key2 = $this-&amp;gt;key2; ... } }</code></pre> <h4>载入JS和CSS</h4> <p>异步加载功能同样支持<strong>静态资源按需加载</strong>的特性,并且用法也很简单</p> <pre><code class="language-php">&amp;lt;?php namespace App\Admin\Renderable; use Dcat\Admin\Support\LazyRenderable; use Dcat\Admin\Admin; class CustomView extends LazyRenderable { // 这里写入需要加载的js和css文件路径 public static $js = [ 'xxx/xxx1.js', 'xxx/xxx2.js', ]; public static $css = [ 'xxx/xxx1.css', 'xxx/xxx2.css', ]; protected function addScript() { Admin::script( &amp;lt;&amp;lt;&amp;lt;JS console.log('JS脚本都加载完了~'); JS ); } public function render() { // 添加你的 JS 代码 $this-&amp;gt;addScript(); return view('admin.custom', ['...']); } }</code></pre> <p>模板文件代码示例,注意不要包含<code>body</code>和<code>html</code>等标签</p> <pre><code class="language-HTML">&amp;lt;div id=&amp;quot;custom&amp;quot; class=&amp;quot;custom&amp;quot;&amp;gt;&amp;lt;h2&amp;gt;异步加载功能&amp;lt;/h2&amp;gt;&amp;lt;/div&amp;gt; &amp;lt;script&amp;gt; Dcat.ready(function () { // JS 代码也可以放在模板文件中 console.log('模板文件执行js~'); }); &amp;lt;/script&amp;gt;</code></pre> <h3>Dcat\Admin\Widgets\Lazy</h3> <h4>onLoad</h4> <p>通过此方法可以监听异步加载完成事件</p> <pre><code class="language-php">use App\Admin\Renderable\PostChart; use Dcat\Admin\Widgets\Lazy; $chart = Lazy::make(PostChart::make())-&amp;gt;onLoad( &amp;lt;&amp;lt;&amp;lt;JS console.log('组件渲染完成'); JS );</code></pre> <h4>load</h4> <p>此方法可以控制是否立即渲染异步组件,默认值是<code>true</code></p> <pre><code class="language-php">use App\Admin\Renderable\PostChart; use Dcat\Admin\Widgets\Lazy; use Dcat\Admin\Admin; $lazy = Lazy::make(PostChart::make())-&amp;gt;load(false); Admin::script( &amp;lt;&amp;lt;&amp;lt;JS setTimeout(function () { // 3秒后自动触发异步渲染事件 {$lazy-&amp;gt;getLoadScript()} }, 3000); JS );</code></pre> <h4>JS事件</h4> <pre><code class="language-php">use App\Admin\Renderable\PostChart; use Dcat\Admin\Widgets\Lazy; use Dcat\Admin\Admin; $lazy = Lazy::make(PostChart::make()); Admin::script( &amp;lt;&amp;lt;&amp;lt;JS // 手动触发异步渲染事件 $('{$lazy-&amp;gt;getElementSelector()}').trigger('lazy:load'); // 监听渲染完成事件 $('{$lazy-&amp;gt;getElementSelector()}').on('lazy:loaded', function () { console.log('组件渲染完成了') }); JS );</code></pre> <p>&lt;a name=&quot;lazy-table&quot;&gt;&lt;/a&gt;</p> <h2>异步加载数据表格</h2> <p>如果需要异步异步加载数据表格,则定义渲染类时需要继承<code>Dcat\Admin\Grid\LazyRenderable</code></p> <pre><code class="language-php">&amp;lt;?php namespace App\Admin\Renderable; use Dcat\Admin\Grid; use Dcat\Admin\Grid\LazyRenderable; use Dcat\Admin\Models\Administrator; class UserTable extends LazyRenderable { // 指定翻译文件名称 protected $translation = 'user'; public function grid(): Grid { return Grid::make(new Administrator(), function (Grid $grid) { $grid-&amp;gt;column('id'); $grid-&amp;gt;column('username'); $grid-&amp;gt;column('name'); $grid-&amp;gt;column('created_at'); $grid-&amp;gt;column('updated_at'); $grid-&amp;gt;quickSearch(['id', 'username', 'name']); $grid-&amp;gt;paginate(10); $grid-&amp;gt;disableActions(); $grid-&amp;gt;filter(function (Grid\Filter $filter) { $filter-&amp;gt;like('username')-&amp;gt;width(4); $filter-&amp;gt;like('name')-&amp;gt;width(4); }); }); } }</code></pre> <p>使用</p> <pre><code class="language-php">use App\Admin\Renderable\UserTable; use Dcat\Admin\Widgets\Modal; use Dcat\Admin\Layout\Content; public function index(Content $content) { $modal = Modal::make() -&amp;gt;lg() -&amp;gt;title('异步加载 - 表格') -&amp;gt;body(UserTable::make()) // Modal 组件支持直接传递 渲染类实例 -&amp;gt;button('打开表格'); return $content-&amp;gt;body($modal); }</code></pre> <p>效果</p> <p>&lt;a href=&quot;<a href="https://cdn.learnku.com/uploads/images/202008/23/38389/HiAMIvKext.gif!large&quot">https://cdn.learnku.com/uploads/images/202008/23/38389/HiAMIvKext.gif!large&quot</a>; target=&quot;_blank&quot;&gt; <img src="https://cdn.learnku.com/uploads/images/202008/23/38389/HiAMIvKext.gif!large" alt="" /> &lt;/a&gt;</p> <p>同样渲染类的实例也可以附加到 <code>Dcat\Admin\Widgets\Card</code>、<code>Dcat\Admin\Widgets\Box</code>、<code>Dcat\Admin\Widgets\Tab</code>等组件中</p> <pre><code class="language-php">use App\Admin\Renderable\UserTable; use Dcat\Admin\Widgets\Card; $table = UserTable::make(); $card = Card::make('标题', $table)-&amp;gt;withHeaderBorder();</code></pre> <p>以上代码渲染<code>UserTable</code>实例时,其实是底层自动加上了<code>Dcat\Admin\Widgets\LazyTable</code>类实例,以上代码等同于</p> <pre><code class="language-php">use App\Admin\Renderable\UserTable; use Dcat\Admin\Widgets\Card; use Dcat\Admin\Widgets\LazyTable; $table = LazyTable::make(UserTable::make()-&amp;gt;simple()); $card = Card::make('标题', $table)-&amp;gt;withHeaderBorder();</code></pre> <h3>Dcat\Admin\Grid\LazyRenderable</h3> <p><code>Dcat\Admin\Grid\LazyRenderable</code>用于异步渲染数据表格,是<code>Dcat\Admin\Support\LazyRenderable</code>的子类</p> <h4>简化模式</h4> <p>此功能会去除简化一些数据表格默认开启的功能,默认不启用</p> <pre><code class="language-php">use App\Admin\Renderable\UserTable; use Dcat\Admin\Widgets\LazyTable; use Dcat\Admin\Layout\Content; public function index(Content $content) { $table = UserTable::make()-&amp;gt;simple(); return $content-&amp;gt;body(LazyTable::make($table)); }</code></pre> <p>注意,如果把渲染类实例直接注入到<code>Dcat\Admin\Widgets\Card</code>、<code>Dcat\Admin\Widgets\Box</code>、<code>Dcat\Admin\Widgets\Tab</code>和<code>Dcat\Admin\Widgets\Modal</code>等组件时,则会自动启用<code>simple</code>模式</p> <pre><code class="language-php">use App\Admin\Renderable\UserTable; use Dcat\Admin\Widgets\Card; // 这里会自动启用 simple 模式 $card = Card::make('标题', UserTable::make())-&amp;gt;withHeaderBorder();</code></pre> <p>如果你不希望启用 simple 模式,可以传入 LazyTable 实例</p> <pre><code class="language-php">use App\Admin\Renderable\UserTable; use Dcat\Admin\Widgets\Card; use Dcat\Admin\Widgets\LazyTable; $table = LazyTable::make(UserTable::make()); $card = Card::make('标题', $table)-&amp;gt;withHeaderBorder();</code></pre> <h3>Dcat\Admin\Widgets\LazyTable</h3> <h4>onLoad</h4> <p>通过此方法可以监听异步加载完成事件</p> <pre><code class="language-php">use App\Admin\Renderable\PostChart; use Dcat\Admin\Widgets\Lazy; $chart = Lazy::make(PostChart::make())-&amp;gt;onLoad( &amp;lt;&amp;lt;&amp;lt;JS console.log('组件渲染完成'); JS );</code></pre> <h4>load</h4> <p>此方法可以控制是否立即渲染异步组件,默认值是<code>true</code></p> <pre><code class="language-php">use App\Admin\Renderable\UserTable; use Dcat\Admin\Widgets\LazyTable; use Dcat\Admin\Admin; $lazy = LazyTable::make(UserTable::make())-&amp;gt;load(false); Admin::script( &amp;lt;&amp;lt;&amp;lt;JS setTimeout(function () { // 3秒后自动触发异步渲染事件 {$lazy-&amp;gt;getLoadScript()} }, 3000); JS );</code></pre> <h4>JS事件</h4> <pre><code class="language-php">use App\Admin\Renderable\UserTable; use Dcat\Admin\Widgets\LazyTable; use Dcat\Admin\Admin; $lazy = LazyTable::make(UserTable::make()); Admin::script( &amp;lt;&amp;lt;&amp;lt;JS // 手动触发异步渲染事件 $('{$lazy-&amp;gt;getElementSelector()}').trigger('table:load'); // 监听渲染完成事件 $('{$lazy-&amp;gt;getElementSelector()}').on('table:loaded', function () { console.log('组件渲染完成了') }); JS );</code></pre> <p>&lt;a name=&quot;lazy-form&quot;&gt;&lt;/a&gt;</p> <h2>异步加载工具表单</h2> <p>定义工具表单类,实现<code>Dcat\Admin\Contracts\LazyRenderable</code>,并载入<code>Dcat\Admin\Traits\LazyWidget</code>这个<code>trait</code></p> <pre><code class="language-php">&amp;lt;?php namespace App\Admin\Forms; use Dcat\Admin\Contracts\LazyRenderable; use Dcat\Admin\Traits\LazyWidget; use Dcat\Admin\Widgets\Form; class UserProfile extends Form implements LazyRenderable { use LazyWidget; // 指定翻译文件名称 protected $translation = 'user-profile'; public function handle(array $input) { return $this-&amp;gt;response()-&amp;gt;success('保存成功'); } public function form() { $this-&amp;gt;text('name', trans('admin.name'))-&amp;gt;required()-&amp;gt;help('用户昵称'); $this-&amp;gt;image('avatar', trans('admin.avatar'))-&amp;gt;autoUpload(); $this-&amp;gt;password('old_password', trans('admin.old_password')); $this-&amp;gt;password('password', trans('admin.password')) -&amp;gt;minLength(5) -&amp;gt;maxLength(20) -&amp;gt;customFormat(function ($v) { if ($v == $this-&amp;gt;password) { return; } return $v; }) -&amp;gt;help('请输入5-20个字符'); $this-&amp;gt;password('password_confirmation', trans('admin.password_confirmation')) -&amp;gt;same('password') -&amp;gt;help('请输入确认密码'); } }</code></pre> <p>使用</p> <pre><code class="language-php">use App\Admin\Forms\UserProfile; use Dcat\Admin\Widgets\Modal; use Dcat\Admin\Layout\Content; public function index(Content $content) { $modal = Modal::make() -&amp;gt;lg() -&amp;gt;title('异步加载 - 表单') -&amp;gt;body(UserProfile::make()) // Modal 组件支持直接传递渲染类实例 -&amp;gt;button('打开表单'); return $content-&amp;gt;body($modal); }</code></pre> <p>效果</p> <p><img src="https://cdn.learnku.com/uploads/images/202008/20/38389/C8InwPTsQG.gif!large" alt="" /></p> <p>当然异步表单实例,也可以在其他组件中使用</p> <pre><code class="language-php">use App\Admin\Forms\UserProfile; use Dcat\Admin\Widgets\Lazy; use Dcat\Admin\Widgets\Card; $form = UserProfile::make(); // 直接传递到 Card 组件中 $card = Card::make($form); // 等同于 $card = Card::make(Lazy::make($form));</code></pre> <h3>传递自定义参数</h3> <p>给异步表单传递参数非常简单,修改上面表单类如下</p> <pre><code class="language-php">&amp;lt;?php namespace App\Admin\Forms; use Dcat\Admin\Contracts\LazyRenderable; use Dcat\Admin\Traits\LazyWidget; use Dcat\Admin\Widgets\Form; class UserProfile extends Form implements LazyRenderable { use LazyWidget; public function handle(array $input) { // 获取外部传递的参数 $key1 = $this-&amp;gt;payload['key1'] ?? null; $key2 = $this-&amp;gt;payload['key1'] ?? null; return $this-&amp;gt;response()-&amp;gt;success('保存成功'); } public function form() { // 获取外部传递的参数 $key1 = $this-&amp;gt;payload['key1'] ?? null; $key2 = $this-&amp;gt;payload['key1'] ?? null; $this-&amp;gt;text('name', trans('admin.name'))-&amp;gt;required()-&amp;gt;help('用户昵称'); $this-&amp;gt;image('avatar', trans('admin.avatar'))-&amp;gt;autoUpload(); $this-&amp;gt;password('old_password', trans('admin.old_password')); $this-&amp;gt;password('password', trans('admin.password')) -&amp;gt;minLength(5) -&amp;gt;maxLength(20) -&amp;gt;customFormat(function ($v) { if ($v == $this-&amp;gt;password) { return; } return $v; }) -&amp;gt;help('请输入5-20个字符'); $this-&amp;gt;password('password_confirmation', trans('admin.password_confirmation')) -&amp;gt;same('password') -&amp;gt;help('请输入确认密码'); } public function default() { // 获取外部传递的参数 $key1 = $this-&amp;gt;payload['key1'] ?? null; $key2 = $this-&amp;gt;payload['key1'] ?? null; return [ 'name' =&amp;gt; '...', ]; } }</code></pre> <p>传递参数代码如下</p> <pre><code class="language-php">// 传递自定义参数 $form = UserProfile::make()-&amp;gt;payload(['key1' =&amp;gt; '...', 'key2' =&amp;gt; '...']); $modal = Modal::make() -&amp;gt;lg() -&amp;gt;title('异步加载 - 表单') -&amp;gt;body($form) -&amp;gt;button('打开表单');</code></pre>

页面列表

ITEM_HTML