在 laravel vue 中使用 svg 图标
发表于|更新于|码不能停
|总字数:200|阅读时长:1分钟|浏览量:
在 laravel vue 中使用 svg 图标
安装扩展组件:
1 | npm install laravel-mix-svg-vue |
在 webpack.mix.js 中添加引用:
1 | const mix = require('laravel-mix'); |
在 app.js 中引用组件
1 | import Vue from 'vue'; |
svg 使用:
1 | <svg-vue icon="avatar"></svg-vue> |
默认配置
1 | { |
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| svgPath | String | resources/svg | svg 图标路径 |
| extract | Boolean | false | 将 svg 与主包分离 |
| svgoSettings | Array | [{ removeTitle: true }, { removeViewBox: false }, { removeDimensions: true }] | svgo 相关设置 |
缺点
好像是不能通过参数动态改变 svg 内容,没试出来,不知道什么原因。
文章作者: m-finder
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 M-finder!
相关推荐

2018-01-05
laravel5.4疑难杂症
公司项目最近翻新了页面,把 bootstrap 完全改成了 layui 。 按照惯例,上线之前先在测试环境跑几天,结果在搭建测试环境的时候,问题就出来了: laravel 版本是 5.4.63 ,服务器的 php 版本是 5.6 ,执行 composer install 时,提示我需要 php7.1 。 吓得我一阵懵逼,难道是什么时候装错扩展了? 把 composer.json 里没什么用的扩展完全去除后再试,结果还是一样。 反复折腾无果,想起还有 update 可以用,遂改为执行 composer update ,终于开始安装了。 小样,还治不了你了!容老夫抽根烟得瑟一下。 下一秒,一个新的报错又砸我个措手不及: class ‘’ not found ! 虽然不知道这个报错是咋回事,但是潜意识觉得应该是某个 Kernel 文件出错了。 找到一份之前的备份,一通对比,终于有所发现: 出错的代码比之前正常的代码多了个 “,”,丫的,太粗糙了! 去掉,再次执行 update ,果然一路畅通无阻。 但是那个该死的 install 是再也没回来。

2019-03-15
Laravel 生命周期
Laravel 的生命周期主要分为四个阶段: 加载依赖 创建应用实例 接收请求并响应 请求结束进行回调 这四个阶段都在 index.php 中完成: 1234567891011121314151617181920<?php// 加载依赖require __DIR__.'/../vendor/autoload.php';// 创建应用实例$app = require_once __DIR__.'/../bootstrap/app.php';// 实例化 HTTP 内核$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);// 接收请求,生成响应$response = $kernel->handle( $request = Illuminate\Http\Request::capture());// 发送响应$response->send();// 请求结束,进行回调$kernel->terminate($request, $response); 1. 加载依赖laravel 框架依赖 composer 管理扩展包,通过引入 composer 的自动加载程序,就可以轻松完成扩展加载: 1require __DIR__.'/../vendor/autoload.php'; 2 创建应用实例这一步主要由以下几个小步骤组成: 创建应用实例 完成基础注册 基础绑定 基础服务提供者注册 event log route 核心类别名注册 绑定核心 创建应用实例,由 bootstrap/app.php 完成,然后注册三个核心。 1234567<?php// 第一部分: 创建应用实例$app = new Illuminate\Foundation\Application( realpath(__DIR__.'/../'));…… 2.1 完成基础注册应用实例创建后,再来看一下具体是怎么工作的,打开 Illuminate\Foundation\Application,其代码如下: 1234567891011121314public function __construct($basePath = null){ // 应用的路径绑定 if ($basePath) { $this->setBasePath($basePath); } // 将基础绑定注册到容器中,容器名 $this->registerBaseBindings(); // 将基础服务提供者注册到容器 Event、Log、Route $this->registerBaseServiceProviders(); // 将核心类别名注册到容器 $this->registerCoreContainerAliases();} 2.2 内核绑定接着看 bootstrap/app.php 中的代码: 12345678910111213141516171819……// 第二步,内核绑定$app->singleton( Illuminate\Contracts\Http\Kernel::class, App\Http\Kernel::class);$app->singleton( Illuminate\Contracts\Console\Kernel::class, App\Console\Kernel::class);$app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class); 绑定三个内核,HTTP、Console、Exception内核。 3 接收请求并响应再次回到 index.php,查看请求和响应的相关代码: 1234567891011……$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);$response = $kernel->handle( $request = Illuminate\Http\Request::capture());$response->send();…… 这一步也是由几个小步骤组成: 实例化 HTTP 核心 实例化内核 注册中间件到路由 session 共享错误 身份验证请求 …… 请求处理 创建请求实例 处理请求,返回响应 发送响应 3.1 注册中间件到路由在 Illuminate\Contracts\Http\Kernel::class 类的构造方法中,将在 HTTP 内核定义的「中间件」注册到路由,注册完后就可以在实际处理 HTTP 请求前调用这些「中间件」实现过滤请求的目的。 1234567891011121314151617181920212223242526272829303132protected $middlewarePriority = [ \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class, \Illuminate\Routing\Middleware\ThrottleRequests::class, \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class,];public function __construct(Application $app, Router $router){ $this->app = $app; $this->router = $router; $this->syncMiddlewareToRouter();}// 注册中间件到路由protected function syncMiddlewareToRouter(){ $this->router->middlewarePriority = $this->middlewarePriority; foreach ($this->middlewareGroups as $key => $middleware) { $this->router->middlewareGroup($key, $middleware); } foreach ($this->routeMiddleware as $key => $middleware) { $this->router->aliasMiddleware($key, $middleware); }} 3.2 处理请求处理请求实际包含两个阶段: 创建请求实例 处理请求 3.2.1 创建请求实例通过 Symfony 实例创建一个 Laravel 请求实例。 12345678910111213141516171819202122public static function capture(){ static::enableHttpMethodParameterOverride(); return static::createFromBase(SymfonyRequest::createFromGlobals());}public static function createFromBase(SymfonyRequest $request){ $newRequest = (new static)->duplicate( $request->query->all(), $request->request->all(), $request->attributes->all(), $request->cookies->all(), $request->files->all(), $request->server->all() ); $newRequest->headers->replace($request->headers->all()); $newRequest->content = $request->content; $newRequest->request = $newRequest->getInputSource(); return $newRequest;} 3.2.2 处理请求在 HTTP 核心的 handdle 方法内,接收一个请求,也就是上一步创建的请求实例,最终生成一个响应。 主要步驟如下: 注册请求到容器 运行引导程序 环境检测,将 env 中的配置读取到变量中 配置文件加载 加载异常处理 注册门面 注册服务提供者 服务启动 发送请求到路由 查找路由 运行控制器或匿名函数 返回响应 HTTP 核心的 handle 方法: 123456789101112131415161718public function handle($request){ try { $request->enableHttpMethodParameterOverride(); $response = $this->sendRequestThroughRouter($request); } catch (Throwable $e) { $this->reportException($e); $response = $this->renderException($request, $e); } $this->app['events']->dispatch( new RequestHandled($request, $response) ); return $response;} 再往下深入,查看 $response = $this->sendRequestThroughRouter($request); 的具体实现: 12345678910111213141516protected function sendRequestThroughRouter($request){ // 将请求注册到容器 $this->app->instance('request', $request); Facade::clearResolvedInstance('request'); // 启动引导程序 $this->bootstrap(); // 发送请求至路由 return (new Pipeline($this->app)) ->send($request) ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware) ->then($this->dispatchToRouter());} 首先,将 request 注册到容器内,然后清除掉之前的 request 实例缓存,启动引导程序,然后将请求发送到路由。 接下来,看一下引导程序是做什么的: 12345678910111213141516171819202122232425262728293031323334protected $bootstrappers = [ \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class, \Illuminate\Foundation\Bootstrap\LoadConfiguration::class, \Illuminate\Foundation\Bootstrap\HandleExceptions::class, \Illuminate\Foundation\Bootstrap\RegisterFacades::class, \Illuminate\Foundation\Bootstrap\RegisterProviders::class, \Illuminate\Foundation\Bootstrap\BootProviders::class,];public function bootstrap(){ if (! $this->app->hasBeenBootstrapped()) { $this->app->bootstrapWith($this->bootstrappers()); }}protected function bootstrappers(){ return $this->bootstrappers;}// src/Illuminate/Foundation/Application.phppublic function bootstrapWith(array $bootstrappers){ $this->hasBeenBootstrapped = true; foreach ($bootstrappers as $bootstrapper) { $this['events']->dispatch('bootstrapping: '.$bootstrapper, [$this]); $this->make($bootstrapper)->bootstrap($this); $this['events']->dispatch('bootstrapped: '.$bootstrapper, [$this]); }} 在容器内的具体实现方法中,会先解析引导程序,然后再通过调用引导程序的 bootstrap 方法来启动服务。引导程序功能: 环境检测,将 env 配置文件载入到 $_ENV 变量中 加载配置文件 加载异常处理 加载 Facades,注册完成后可以用别名的方式访问具体的类 注册服务提供者,在这里我们会将配置在 app.php 文件夹下 providers 节点的服务器提供者注册到 APP 容器,供请求处理阶段使用 服务启动 在发送请求至路由这行代码中,完成了:管道(pipeline)创建、将 request 传入管道、对 request 执行中间件处理和实际的请求处理四个不同的操作。 1234return (new Pipeline($this->app)) ->send($request) ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware) ->then($this->dispatchToRouter()); 继续深入 $this->dispatchToRouter(),分析程序是如何处理请求的: 注册请求 查找路由 运行控制器 返回响应结果 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364protected function dispatchToRouter(){ return function ($request) { // 将请求注册到容器 $this->app->instance('request', $request); return $this->router->dispatch($request); };}public function dispatch(Request $request){ $this->currentRequest = $request; return $this->dispatchToRoute($request);}public function dispatchToRoute(Request $request){ return $this->runRoute($request, $this->findRoute($request));}// 查找路由protected function findRoute($request){ $this->current = $route = $this->routes->match($request); $this->container->instance(Route::class, $route); return $route;}protected function runRoute(Request $request, Route $route){ $request->setRouteResolver(function () use ($route) { return $route; }); $this->events->dispatch(new RouteMatched($route, $request)); return $this->prepareResponse($request, $this->runRouteWithinStack($route, $request) );}protected function runRouteWithinStack(Route $route, Request $request){ $shouldSkipMiddleware = $this->container->bound('middleware.disable') && $this->container->make('middleware.disable') === true; $middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route); // 返回运行结果 return (new Pipeline($this->container)) ->send($request) ->through($middleware) ->then(function ($request) use ($route) { // 运行匹配到的路由控制器或匿名函数 return $this->prepareResponse( $request, $route->run() ); });} 执行 $route->run() 的方法定义在 Illuminate\Routing\Route 类中: 1234567891011121314public function run(){ $this->container = $this->container ?: new Container; try { if ($this->isControllerAction()) { return $this->runController(); } return $this->runCallable(); } catch (HttpResponseException $e) { return $e->getResponse(); }} 如果路由的实现是一个控制器,会完成控制器实例化并执行指定方法;如果是一个匿名函数就会直接调用。最终响应通过 prepareResponse 返回。 3.2.3 发送响应绕了一大圈,最后终于回到了开始的地方 12// 发送响应$response->send(); 最终发送,由 src/Illuminate/Http/Response.php 的父类 Symfony\Component\HttpFoundation\Response 完成: 12345678910111213public function send(){ $this->sendHeaders(); $this->sendContent(); if (\function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } elseif (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) { static::closeOutputBuffers(0, true); } return $this;} 4 请求结束,进行回调1$kernel->terminate($request, $response); 继续往下看,核心的 terminate 方法: 123456public function terminate($request, $response){ $this->terminateMiddleware($request, $response); $this->app->terminate();} terminateMiddleware 中,进行终止中间件,$this->app->terminate() 终止程序。 总结创建应用实例,完成项目路径注册、基础服务注册、核心类别名注册,然后将 HTTP 和 Console, Exception 核心注册到容器。 然后再实例化内核,将中间件加载到路由,再将请求注册到容器,然后运行引导程序,进行环境检测、加载系统配置等系统环境配置。 然后进行中间件校验,通过校验后才会最终处理实际的控制器或匿名函数并生成响应。 最终,发送响应给用户,清理项目中的中间件,完成一个请求周期。

2019-04-09
laravel 队列学习
学习下 laravel 的队列系统。 队列的目的是将耗时的任务延时处理,比如发送邮件,从而大幅度缩短 Web 请求和相应的时间。 常用的队列后台有: Beanstalk,Amazon SQS,Redis 等。 配置laravel 为多种队列服务做了统一的API,在配置文件 config/queue.php 中可以找到每种队列驱动的配置。 其中每种驱动都有一个默认的 queue 属性,用来存放使用时没有显示定义队列的任务。 12345// 分发到默认队列Job::dispatch();// 分发到 emails 队列Job::dispatch()->onQueue('emails'); 在项目的配置文件中,可以指定驱动,老版本中为 QUEUE_DRIVER,新版本中为QUEUE_CONNECTION , 驱动默认为 sync,这是一个本地的同步驱动,方便调试队列里的任务。 先以 redis 为例做一个邮件发送队列。 因为 laravel 的 redis 默认使用了 predis,所以先装下扩展: 1composer require 'predis/predis' 邮件配置,最后两项是手动添加的,否则会报错: 12345678MAIL_DRIVER=smtpMAIL_HOST=smtp.mxhichina.comMAIL_PORT=25MAIL_USERNAME=m@m-finder.comMAIL_PASSWORD=xxxxxxMAIL_ENCRYPTION=nullMAIL_FROM_NAME=M-finderMAIL_FROM_ADDRESS=m@m-finder.com 生成任务类命令行执行:php artisan make:job EmailJob,该命令会在 app/jobs 下自动创建文件。 在任务类中发送邮件: 12345678public function handle() { $email = $this->email; $content = '这是一封来自Laravel的队列测试邮件.'; Mail::raw($content, function ($message) use ($email) { $message->subject('[ 测试 ] 测试邮件SendMail - ' . date('Y-m-d H:i:s')); $message->to($email); });} 任务调度之前弄了登录事件和监听,就在监听里去触发吧。 1EmailJob::dispatch($guard->user)->onQueue('emails'); 开启队列1php artisan queue:work --tries=3 --timeout=30 --queue=emails 然后重新登录触发任务。可以看到邮箱已经有了提示: 邮件已经成功发出,接下来就可以在实际的需求中使用了。

2021-04-21
laravel 导入 excel 报错排查记录
今天公司项目导入 excel 时突遇一个报错:Undefined index: Sheet1,一下给我整懵逼了,一通排查,发现是因为执行过 composer update,把一个包升级到了最高,然后,它就不能用了。 看官方 issues 说: This is a known bug in PhpSpreadsheet PHPOffice/PhpSpreadsheet#1895. Until they release a new version, you have to lock the phpspreadsheet version to 1.16 啥意思呢,翻译一下吧:这是PhpSpreadsheet PHPOffice / PhpSpreadsheet#1895中的一个已知错误。在他们发布新版本之前,您必须将phpspreadsheet版本锁定为1.16 版本太高有时候也不是个好事呀! issuse

2019-04-12
laravel 广播系统学习
看到广播系统,先想起了曾经虐过我的即时通讯。 虽然都是对 websocket 的应用,但是好像又有点区别,这里好好学习一下。 laravel 的广播与事件紧密相关,广播即对事件进行广播,因此在学习广播之前,要先阅读事件和监听器的相关文档。 配置老规矩,先来看配置文件 config/broadcasting.php 里边的配置选项: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960<?phpreturn [ /* |-------------------------------------------------------------------------- | Default Broadcaster |-------------------------------------------------------------------------- | | This option controls the default broadcaster that will be used by the | framework when an event needs to be broadcast. You may set this to | any of the connections defined in the "connections" array below. | | Supported: "pusher", "redis", "log", "null" | */ 'default' => env('BROADCAST_DRIVER', 'null'), /* |-------------------------------------------------------------------------- | Broadcast Connections |-------------------------------------------------------------------------- | | Here you may define all of the broadcast connections that will be used | to broadcast events to other systems or over websockets. Samples of | each available type of connection are provided inside this array. | */ 'connections' => [ 'pusher' => [ 'driver' => 'pusher', 'key' => env('PUSHER_APP_KEY'), 'secret' => env('PUSHER_APP_SECRET'), 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), 'encrypted' => true, ], ], 'redis' => [ 'driver' => 'redis', 'connection' => 'default', ], 'log' => [ 'driver' => 'log', ], 'null' => [ 'driver' => 'null', ], ],]; 默认情况下,laravel 提供了以上几种开箱即用的广播驱动器程序。 env 配置文件中,默认的驱动为 log,意味着客户端不会受到任何信息,只是会把要广播的消息写入 log 文件中,跟学习目标不符,就先以 pusher 展开学习吧。 我们就以发布新文章后推送给所有用户为例。 前期准备开始之前,必须要先注册 App\Providers\BroadcastServiceProvider,在 config/app.php 配置文件中的 providers 数组中取消对提供者的注释。 注册: [ pusher ] 然后把相关参数配置到 .env 文件。 安装组件:12composer require pusher/pusher-php-servernpm install --save laravel-echo pusher-js 添加文章模块,包含 migrate,controller,model,view 和 router 等内容。 新建事件:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051php artisan make:event NewArticleNotificationEvent// 事件内容:<?phpnamespace App\Events;use Illuminate\Queue\SerializesModels;use Illuminate\Broadcasting\Channel;use Illuminate\Broadcasting\PrivateChannel;use Illuminate\Foundation\Events\Dispatchable;use Illuminate\Broadcasting\InteractsWithSockets;use Illuminate\Contracts\Broadcasting\ShouldBroadcast;use App\Article;class NewArticleNotificationEvent implements ShouldBroadcast{ use Dispatchable, InteractsWithSockets, SerializesModels; private $article; /** * Create a new event instance. * * @return void */ public function __construct(Article $article) { $this->article = $article; } public function broadcastWith() { return [ 'title' => $this->article->title, 'content' => $this->article->content, 'author' => $this->article->user->name ]; } /** * Get the channels the event should broadcast on. * * @return \Illuminate\Broadcasting\Channel|array */ public function broadcastOn() { return new Channel('articles'); }} 触发事件在保存文章的控制器中触发事件: 123$data = array_merge($request->only(['title', 'content']), ['uid' => Auth::id()]);$article = Article::create($data);broadcast(new NewArticleNotificationEvent($article)); 前端监听文章列表用了vue组件,在这个组件中进行事件监听。 1234567891011121314151617181920212223242526272829303132333435<template> <div class="container"> <table class="table table-striped"> <tr> <th>ID</th> <th>Author</th> <th>Title</th> <th>Content</th> <th>Created At</th> </tr> <tr v-for="article in articles"> <td>{{article.id}}</td> <td>{{article.user.name}}</td> <td>{{article.title}}</td> <td>{{article.content}}</td> <td>{{article.created_at}}</td> </tr> </table> </div></template><script>export default { props: ['articles'], created() { Echo.channel('articles').listen('NewArticleNotificationEvent', (article) => { console.log(article); }) }}</script><style scoped></style> 写好后要在命令行执行 npm run watch-poll 实时编译文件。 测试写篇文章测试一下: 注意事项 不需要创建 channel 路由 不需要开启队列监听 如果没反应请先强制刷新浏览器

2019-03-14
laravel 内置 vue 的使用
从 5.3 版本开始,用 Vue.js 作为默认 JavaScript 前端框架。 从刚接触 laravel 到现在已经又过去了四个版本,种种原因,还是一直没能用上 vue.js 来做开发,现在刚好因为公司项目用到了 vue,对 vue 有了一定的了解,所以顺便就研究下 vue 在 laravel 中的使用吧。 安装laravel操作均在 laradock 的环境中进行。进入 workspace 容器,执行以下命令安装 laravel 1composer create-project laravel/laravel study 配置mysqldocker-compose up -d nginx mysql phpmyadmin 启动容器配置 nginx、hosts 并重启 nginx进入 mysql 容器执行以下命令: 123456mysql -uroot -prootALTER USER root IDENTIFIED WITH mysql_native_password BY 'PASSWORD';exit;exit 访问 phpmyadmin: localhost:8080,host 填写 mysql,用户名密码均为 root。 配置laravel修改数据库信息,生成用户模块并安装前端脚手架: 1234567891011121314php artisan make:authphp artisan migratephp artisan make:seed UsersTableSeeder在 run 方法中添加用户信息:$user = new App\User;$user->name = 'wu';$user->email = 'yf-wu@qq.com';$user->password = Hash::make('111111');$user->save();再去 DatabaseSeeder 中打开 run 中的注释,接着往下执行:php artisan db:seednpm install 修改视图home.blade.php:vue 的组件在 resources/js/components,然后在 app.js 中注册。 12You are logged in!<example-component></example-component> 更新脚手架:npm run dev or npm run watch 再实验下例子来自:[ cxp1539 ] 视图组件: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657<template> <transition name="fade"> <div v-if="isShow" class="goTop" @click="goTop"> <span class="glyphicon glyphicon-menu-up"></span> </div> </transition></template><script>export default { data() { return { isShow: false } }, mounted() { const that = this $(window).scroll(function() { if ($(this).scrollTop() > 50) { that.isShow = true } else { that.isShow = false } }) }, methods: { goTop() { $('html,body').animate({ scrollTop: 0 }) } }}</script><style scoped lang="scss"> .fade-enter-active, .fade-leave-active { transition: opacity .5s; } .fade-enter, .fade-leave-to { opacity: 0; } .goTop { position: fixed; right: 36px; bottom: 50px; background: #FFF; width: 50px; height: 50px; line-height: 60px; text-align: center; border-radius: 2px; box-shadow: 0 4px 12px 0 rgba(7,17,27,.1); cursor: pointer; z-index: 1000; span { font-size: 20px; } }</style> app.js 注册: 1Vue.component('go-top', require('./components/GoTop.vue')); 在 app.blade.php 中引入组件: 1234<main class="py-4"> @yield('content')</main><go-top></go-top> 为了使页面更高,随便修改个样式使滚动条出现。 注意事项 每次修改组件后都需要重新运行一次 npm run dev,也可以用 watch-poll 监听。 进阶使用到了上一步已经可以完成一些基础的操作了,实际上,刚才得操作还用到了一个叫做 laravel-mix 的东西,在 [ LearnKu ] (laravel-china 社区)社区的文档中是这么介绍的: Laravel Mix 提供了简洁且可读性高的 API ,用于使用几个常见的 CSS 和 JavaScript 预处理器为应用定义 Webpack 构建步骤。可以通过简单链式调用来定义资源的编译。 Laravel Mix 是叠加于 webpack 上的一层干净的膜, 它让 webpack 百分之80的用例变得十分简单。 也就是说,laravel-mix 是用来简化 webpack 学习和开发成本的工具。 对于后端人员来说,前端东西真的太多太难,mix 可以让我们不需要关注 webpack 的配置,即可轻松的编译前端脚本。 之前因为没在框架中用过 vue,所以一直也没有接触到这个工具,现在看完发现,学习之路真的是永无止境… 😂