Laravel框架实现多个视图共享相同数据的方法详解


Posted in PHP onJuly 09, 2019

本文实例讲述了Laravel框架实现多个视图共享相同数据的方法。分享给大家供大家参考,具体如下:

最近在用Laravel写一个cms,还没有完成,但是也遇到了许多难点,比如cms后台每个视图都要展示相同的导航菜单数据。

环境:

PHP 7.1
Apache 2.4
MySQL 5.7
Laravel 5.4

  • 传统方法

假设使用传统的方法,应该是在每个控制器中都调用数据,然后把数据都塞给视图。

    $menu = DB::table('menu')->get();
    return view('xx',['menu'=>$menu]);
  • 稍微优化
  • 新建一个BaseController,然后让BaseController去获取数据,然后在每个控制器都继承BaseController,最后将数据塞到视图中。

    基类

    class BaseController{
      protected $menu = null;//菜单数据
      public function __construct(){
        $this->getMenu();//获取导航菜单
      }
      public function getMenu(){
        $this->menu = DB::table('menu')->get();
      }
    }

    A控制器

    class AController extends BaseController{
      public function index(){
        return view('admin.index',['menu'=>$this->menu,'user'=>$user]);
      }
    }

    缺点:在每个控制器中都需要重新设置相同的模板的数据(menu)

    • 最好优化方案

    使用Laravel中的View Composers来解决这个问题

    1、在App\Providers下创建一个ComposerServiceProvider类

    <?php
    namespace App\Providers;
    use Illuminate\Support\Facades\View;
    use Illuminate\Support\ServiceProvider;
    class ComposerServiceProvider extends ServiceProvider {
      /**
       * Register bindings in the container.
       *
       * @return void
       */
      public function boot() {
        // 基于类的view composer
        View::composer(
          'admin.common.*', 'App\Http\ViewComposers\AdminComposer'
        );
      }
      /**
       * Register the service provider.
       *
       * @return void
       */
      public function register() {
        //
      }
    }

    在boot方法中定义要监听的视图,还可以使用通配符,这里我写的是admin.common.*,如果admin.common.* 下的视图被渲染的话将会调用App\Http\ViewComposers\AdminComposer@composer 方法

    2、注册ComposerServiceProvider

    config/app.php文件下的providers数组中进行注册

    App\Providers\ComposerServiceProvider::class,

    3、创建AdminComposer类

    Laravel推荐把view composer类放在app\Http\ViewComposers目录下,这个目录一开始是没有的,需要新建

    <?php
    namespace App\Http\ViewComposers;
    use App\Libs\CommonUtils;
    use Illuminate\Http\Request;
    use Illuminate\View\View;
    class AdminComposer {
      private $data = null;//CommonUtils对象
      public function __construct(Request $request) {
        $this->data = new CommonUtils($request);//新建一个CommonUtils对象
      }
      public function compose(View $view) {
        $view->with([
          'admin' => $this->data->admin,
          'mbx' => $this->data->mbx,
          'menu' => $this->data->menu,
          'msg' => $this->data->msg
        ]);//填充数据
      }
    }

    在这里我在构造方法中创建了一个对象,这个对象中包含着数据

    5、CommonUtils文件

    <?php
    /**
     * Created by PhpStorm.
     * User: Administrator
     * Date: 2017/4/20 0020
     * Time: 19:49
     */
    namespace App\Libs;
    use App\Admin;
    use App\Perm;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\DB;
    class CommonUtils {
      public $admin = null;//管理员对象
      public $menu = null;//菜单对象
      public $mbx = null;//面包屑对象
      public $msg = null;//消息对象
      /**
       * 构造函数
       */
      public function __construct(Request $request) {
        $this->init($request);
      }
      /**
       * 初始化函数
       */
      private function init(Request $request) {
        $this->getAdmin($request);
        $this->getMsg();
        $this->getMenu($request);
        $this->getMbx($request);
      }
      /**
       * 获取管理员数据
       */
      private function getAdmin() {
        $this->admin = session('admin');
      }
      /**
       * 获取后台菜单数据
       */
      private function getMenu(Request $request) {
        $menu = DB::table('menu')->where('parentid', 0)->orderBy('sort')->get();
        $router = $request->getPathInfo();
        $perm = new Perm();
        $mbx = $perm->getMbx($router);
        foreach ($menu as $k => $m) {
          $m->active = '';
          //读取子菜单
          $childMenu = DB::table('menu')->where('parentid', $m->id)->orderBy('sort')->get();
          if (count($childMenu) > 0) {
            foreach($childMenu as $v){
              $v->active = '';
              if($mbx[0]->router == $v->router){
                $v->active = 'active';
                $m->active = 'active';
              }
            }
            $m->childMenu = $childMenu;
          } else {
            $m->childMenu = null;
          }
        }
        $this->menu = $menu;
      }
      /**
       * 获取面包屑
       */
      private function getMbx(Request $request) {
        $router = $request->getPathInfo();
        $perm = new Perm();
        $mbx = $perm->getMbx($router);
        $this->mbx = $mbx;
      }
      /**
       * 获取未读消息
       */
      private function getMsg() {
        $adminModel = new Admin();
        $toId = $this->admin->id;
        $this->msg = $adminModel->getUnReadMsg($toId);
      }
    }

    在这里面分别获取了管理员、菜单、面包屑、消息数据,这些数据都是每个后台页面都要使用到的。

    注意:这里我将类定义成了CommonUtils,感觉名字取得不好,CommonUtils是存放在App\Libs下的,这个Libs文件夹是我新建的,用于存放工具类的。如果需要给App\Libs文件夹添加自动加载,需要在composer.json文件里做如下修改。

    Laravel框架实现多个视图共享相同数据的方法详解

    希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。

    PHP 相关文章推荐
    PHP编程风格规范分享
    Jan 15 PHP
    php实现图形显示Ip地址的代码及注释
    Jan 20 PHP
    php中 ob_start等函数截取标准输出的方法
    Jun 22 PHP
    WAMP环境中扩展oracle函数库(oci)
    Jun 26 PHP
    帝国cms常用标签汇总
    Jul 06 PHP
    PHP实现的一致性哈希算法完整实例
    Nov 14 PHP
    php简单的上传类分享
    May 15 PHP
    微信支付开发告警通知实例
    Jul 12 PHP
    PHP实现UTF8二进制及明文字符串的转化功能示例
    Nov 20 PHP
    php实现mysql连接池效果实现代码
    Jan 25 PHP
    phpfpm的作用和用法
    Oct 10 PHP
    php 的多进程操作实践案例分析
    Feb 28 PHP
    Laravel5.1框架注册中间件的三种场景详解
    Jul 09 #PHP
    PHP使用 Pear 进行安装和卸载包的方法详解
    Jul 08 #PHP
    PHP 7.4中使用预加载的方法详解
    Jul 08 #PHP
    php apache开启跨域模式过程详解
    Jul 08 #PHP
    php如何把表单内容提交到数据库
    Jul 08 #PHP
    php利用array_search与array_column实现二维数组查找
    Jul 08 #PHP
    php实现获取近几日、月时间示例
    Jul 06 #PHP
    You might like
    PHP登录环节防止sql注入的方法浅析
    2014/06/30 PHP
    php实现用手机关闭计算机(电脑)的方法
    2015/04/22 PHP
    通过PHP自带的服务器来查看正则匹配结果的方法
    2015/12/24 PHP
    DIV+CSS+JS不间断横向滚动实现代码
    2013/03/19 Javascript
    Vue.js中的图片引用路径的方式
    2017/07/28 Javascript
    Vue组件模板形式实现对象数组数据循环为树形结构(实例代码)
    2017/07/31 Javascript
    AngularJS实现页面跳转后自动弹出对话框实例代码
    2017/08/02 Javascript
    浅谈JavaScript作用域和闭包
    2017/09/18 Javascript
    聊聊JS动画库 Velocity.js的使用
    2018/03/13 Javascript
    Vue子组件向父组件通信与父组件调用子组件中的方法
    2018/06/22 Javascript
    原生JS forEach()和map()遍历的区别、兼容写法及jQuery $.each、$.map遍历操作
    2019/02/27 jQuery
    vue实现百度搜索功能
    2020/12/28 Javascript
    在vue中实现嵌套页面(iframe)
    2020/07/30 Javascript
    详解vue实现坐标拾取器功能示例
    2020/11/18 Vue.js
    JavaScript对象访问器Getter及Setter原理解析
    2020/12/08 Javascript
    python文件操作之目录遍历实例分析
    2015/05/20 Python
    Python计算一个文件里字数的方法
    2015/06/15 Python
    Python和JavaScript间代码转换的4个工具
    2016/02/22 Python
    pycharm使用matplotlib.pyplot不显示图形的解决方法
    2018/10/28 Python
    基于pytorch的lstm参数使用详解
    2020/01/14 Python
    pandas中ix的使用详细讲解
    2020/03/09 Python
    简单了解pytest测试框架setup和tearDown
    2020/04/14 Python
    CSS 说明横向进度条最后显示文字的实现代码
    2020/11/10 HTML / CSS
    HTML5实现表单自动验证功能实例代码
    2017/01/11 HTML / CSS
    HTML5之HTML元素扩展(上)—新增加的元素及使用概述
    2013/01/31 HTML / CSS
    解析HTML5中的新功能本地存储localStorage
    2016/03/01 HTML / CSS
    美国珠宝店:Helzberg Diamonds
    2018/10/24 全球购物
    Lungolivigno Fashion官网:高级时装在线购物
    2020/10/17 全球购物
    寻找迷宫的一条出路,o通路;X:障碍
    2016/07/10 面试题
    配件采购员岗位职责
    2013/12/03 职场文书
    部门年终奖分配方案
    2014/05/07 职场文书
    党性心得体会
    2014/09/03 职场文书
    2014年餐厅服务员工作总结
    2014/11/18 职场文书
    结婚仪式主持词
    2015/06/29 职场文书
    如何起草一份正确的合伙创业协议书?
    2019/07/04 职场文书
    创业计划书之牛肉汤快餐店
    2019/10/08 职场文书