Laravel學習筆記八-經常使用包及用法收集

從本節開始,將學習搭建一個問答模塊的站點,先開始咱們的註冊,登陸,郵箱驗證,信息提示。javascript

1、郵件擴展包Sendcould

項目中,咱們使用Sendcloud做爲咱們的郵件代理服務器。
安裝sendcouldphp

$ composer require naux/sendcloud
$ composer require guzzlehttp/guzzle

sendcloud詳細用法請訪問Github: naux/sendcloudcss

修改 config/app.php,添加服務提供者html

'providers' => [
   // 添加這行
    Naux\Mail\SendCloudServiceProvider::class,
];

.env 中配置你的密鑰, 並修改郵件驅動爲 sendcloudvue

MAIL_DRIVER=sendcloud

SEND_CLOUD_USER=   # 建立的 api_user
SEND_CLOUD_KEY=    # 分配的 api_key

2、命令自動生成註冊登陸模塊

vagrant@homestead:~/Code/my-app$ php artisan make:auth

clipboard.png

laravel5.4 爲咱們帶了開箱即用的用戶註冊系統,只需一個操做命令,便可完成登陸模塊的建立。java

3、信息提示

GitHub安裝開源的信息提示包laracasts/flashnode

composer require laracasts/flash

And then, if using Laravel 5, include the service provider within config/app.php.jquery

'providers' => [
    Laracasts\Flash\FlashServiceProvider::class,
];

laracasts/flash詳細用法請訪問Github: laracasts/flashios

4、多語言翻譯包

clipboard.png

咱們能夠看到,提示的信息爲英文,咱們想轉爲中文,應該怎樣作呢?
GitHub 上有人專門爲此寫了一個擴展包 - Laravel-lang來對 Laravel 提供默認提示信息添加多語言版本翻譯。laravel

接下來讓咱們使用Composer來安裝 Laravel-lang

$ composer require "caouecs/laravel-lang:~3.0"

安裝後的 laravel-lang 擴展包的全部核心文件都將被放置在 vendor/ 文件夾下,其中包括咱們須要的中文語言包,讓咱們將中文語言包提取到 Laravel 默認指定的語言包存放路徑 resources/lang 中。

$ cp -a vendor/caouecs/laravel-lang/src/zh-CN resources/lang

完成以後你即可在 resources/lang/zh-CN 文件夾中看到咱們新增的語言包文件。

最後,咱們還須要將項目語言設置爲中文。
config/app.php

<?php

return [
    .
    .
    .
    'locale' => 'zh-CN',
    .
    .
    .
];

如今再次提交驗證不經過的信息,能看到錯誤提示已變成中文。

clipboard.png

Laravel-lang 詳細用法請訪問 Github:Laravel-lang

5、laravel-ueditor編輯器

項目中咱們使用安正超同窗開源的overtrue/laravel-ueditor編輯器進行開發。
使用方法:

安裝

$ composer require "overtrue/laravel-ueditor:~1.0"

配置

添加下面一行到 config/app.phpproviders 部分:

Overtrue\LaravelUEditor\UEditorServiceProvider::class,

發佈配置文件與資源

$ php artisan vendor:publish

模板引入編輯器

這行的做用是引入編輯器須要的 css,js 等文件,因此你不須要再手動去引入它們。

@include('vendor.ueditor.assets')

編輯器的初始化

<!-- 實例化編輯器 -->
<script type="text/javascript">
    var ue = UE.getEditor('container');
    ue.ready(function() {
        ue.execCommand('serverparam', '_token', '{{ csrf_token() }}'); // 設置 CSRF token.
    });
</script>

<!-- 編輯器容器 -->
<script id="container" name="content" type="text/plain"></script>

laravel-ueditor詳細用法請訪問Github: overtrue/laravel-ueditor

6、select2選擇框使用

很好用的一款選擇框組件,詳細用法請看Select2官網示例。

clipboard.png

CDN:

<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>

用法:

<script type="text/javascript">
  // 初始化
  $('select').select2();
</script>

簡單示例:

<html>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>

<select class="js-example-basic-multiple" multiple="multiple">
  <option value="AL">Alabama</option>
  <option value="WY">Wyoming</option>
</select>

<script type="text/javascript">

    $(".js-example-basic-multiple").select2();

</script>


</html>

或者咱們能夠將上邊的CDN資源文件經過curl -O命令下載到本地項目目錄中:

cd resources/assets/sass/
mk css
~/Code/zhihu-app/resources/assets/sass/css$ curl -O https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css

// 下載js文件
~/Code/zhihu-app/resources/assets/js$ curl -O https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js

實例應用

laravel5.4 中應用 select2 插件:
select2.min.cssselect2.min.js文件通過 gulp編譯後生成app.cssapp.js打包後的文件,而後在總視圖佈局文件/layouts/app.blade.php中應用,

<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Styles -->
    <link href="{{ elixir('css/app.css') }}" rel="stylesheet">

    <!-- Scripts -->
    <script>
        window.Laravel = {!! json_encode([
            'csrfToken' => csrf_token(),
        ]) !!};
    </script>
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-default navbar-static-top">
            <div class="container">
                <div class="navbar-header">

                    <!-- Collapsed Hamburger -->
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse">
                        <span class="sr-only">Toggle Navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>

                    <!-- Branding Image -->
                    <a class="navbar-brand" href="{{ url('/') }}">
                        {{ config('app.name', 'Laravel') }}
                    </a>
                </div>

                <div class="collapse navbar-collapse" id="app-navbar-collapse">
                    <!-- Left Side Of Navbar -->
                    <ul class="nav navbar-nav">
                        &nbsp;
                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="nav navbar-nav navbar-right">
                        <!-- Authentication Links -->
                        @if (Auth::guest())
                            <li><a href="{{ route('login') }}">Login</a></li>
                            <li><a href="{{ route('register') }}">Register</a></li>
                        @else
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
                                    {{ Auth::user()->name }} <span class="caret"></span>
                                </a>

                                <ul class="dropdown-menu" role="menu">
                                    <li>
                                        <a href="{{ route('logout') }}"
                                            onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                            Logout
                                        </a>

                                        <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
                                            {{ csrf_field() }}
                                        </form>
                                    </li>
                                </ul>
                            </li>
                        @endif
                    </ul>
                </div>
            </div>
        </nav>
        @include('shared.messages')
        @yield('content')
    </div>

    <!-- Scripts -->
    <script src="{{ elixir('js/app.js') }}"></script>
    @yield('js')
    <script>
        $('#flash-overlay-modal').modal();
    </script>
</body>
</html>

在底部引用app.js代碼,並添加區塊佈局 yield('js'),在繼承該總佈局頁面時,有關應用js代碼的須要放在 @section('js') 如select2 @endsection中,以下面的這個子頁面 create.blade.php

@extends('layouts.app')

@section('content')
    @include('vendor.ueditor.assets')
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">發佈問題</div>

                    <div class="panel-body">
                        @include("shared.errors")
                        <form action="/questions" method="post">
                            {{ csrf_field() }}
                            <div class="form-group">
                                <label for="title">標題</label>
                                <input type="text" name="title" value="{{ old('title') }}" class="form-control" placeholder="標題" id="title">
                            </div>

                            <div class="form-group">
                                <select class="js-example-basic-multiple  form-control" multiple="multiple">
                                    <option value="AL">Alabama</option>
                                    <option value="WY">Wyoming</option>
                                </select>
                            </div>

                            <!-- 編輯器容器 -->
                            <label for="title">內容</label>
                            <script id="container" name="body" style="height:200px" type="text/plain">
                                {!! old('body') !!}
                            </script>
                            <button class="btn btn-success pull-right" type="submit">發佈問題</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 實例化編輯器 -->
    @section('js')
    <script type="text/javascript">
        var ue = UE.getEditor('container', {
            toolbars: [
                ['bold', 'italic', 'underline', 'strikethrough', 'blockquote', 'insertunorderedlist', 'insertorderedlist', 'justifyleft','justifycenter', 'justifyright',  'link', 'insertimage', 'fullscreen']
            ],
            elementPathEnabled: false,
            enableContextMenu: false,
            autoClearEmptyNode:true,
            wordCount:false,
            imagePopup:false,
            autotypeset:{ indent: true,imageBlockLine: 'center' }
        });
        ue.ready(function() {
            ue.execCommand('serverparam', '_token', '{{ csrf_token() }}'); // 設置 CSRF token.
        });

        // select2,若是沒有預加載ready,不然不會出現
        $(document).ready(function () {
            $(".js-example-basic-multiple").select2();
        });
    </script>
    @endsection

@endsection

clipboard.png

7、axios HTTP請求包

Promise based HTTP client for the browser and node.js

Github地址:mzabriskie/axios

安裝:

$ npm install axios

laravel5.4開始使用 axios作http請求,若是用舊的請求方法,會報這樣的錯誤:

Uncaught TypeError: Cannot read property 'post' of undefined

clipboard.png

具體的代碼:

export default {
    props:['question', 'user'],
    mounted() {

       /**  這種舊的寫法會在Laravel5.4中報錯
        this.$http.post('/api/question/follower', {'question':this.question, 'user':this.user}).then(response => {
            console.log(response.data);
        })
        */
       axios.post('/api/question/follower', {
           'question':this.question,
           'user':this.user
       }).then(function(response){
           console.log(response.data);
       })
    },

8、vue圖片剪裁上傳組件

vue圖片剪裁上傳組件: vue圖片剪裁上傳組件

1.npm 安裝

npm install vue-image-crop-upload

// ES6 依賴
npm install babel-polyfill

2.用法

Example vue@2示例:

<div id="app">
    <a class="btn" @click="toggleShow">set avatar</a>
    <my-upload field="img"
        @crop-success="cropSuccess"
        @crop-upload-success="cropUploadSuccess"
        @crop-upload-fail="cropUploadFail"
        v-model="show"
        :width="300"
        :height="300"
        url="/upload"
        :params="params"
        :headers="headers"
        img-format="png"></my-upload>
    <img :src="imgDataUrl">
</div>

<script>
    import 'babel-polyfill'; // es6 shim
    import Vue from 'vue';
    import myUpload from 'vue-image-crop-upload/upload-2.vue';

    new Vue({
        el: '#app',
        data: {
            show: true,
            params: {
                token: '123456798',
                name: 'avatar'
            },
            headers: {
                smail: '*_~'
            },
            imgDataUrl: '' // the datebase64 url of created image
        },
        components: {
            'my-upload': myUpload
        },
        methods: {
            toggleShow() {
                this.show = !this.show;
            },
            /**
             * crop success
             *
             * [param] imgDataUrl
             * [param] field
             */
            cropSuccess(imgDataUrl, field){
                console.log('-------- crop success --------');
                this.imgDataUrl = imgDataUrl;
            },
            /**
             * upload success
             *
             * [param] jsonData  server api return data, already json encode
             * [param] field
             */
            cropUploadSuccess(jsonData, field){
                console.log('-------- upload success --------');
                console.log(jsonData);
                console.log('field: ' + field);
            },
            /**
             * upload fail
             *
             * [param] status    server api return error status, like 500
             * [param] field
             */
            cropUploadFail(status, field){
                console.log('-------- upload fail --------');
                console.log(status);
                console.log('field: ' + field);
            }
        }
    });
</script>

將上邊的代碼應用到組件 Avatar.vue 中,須要對相關的方法按照組件的要求改一改,data 須要使用函數 return 進行返回。

<template>
    <div style="text-align:center;">
    <my-upload field="img"
    @crop-success="cropSuccess"
    @crop-upload-success="cropUploadSuccess"
    @crop-upload-fail="cropUploadFail"
    v-model="show"
    :width="300"
    :height="300"
    url="/avatar"
    :params="params"
    :headers="headers"
    img-format="png"></my-upload>
        <img :src="imgDataUrl" style="width:80px;">
        <div style="margin-top:20px;">
          <button class="btn btn-default" @click="toggleShow">修改頭像</button>
        </div>
    </div>
</template>

<script>
import 'babel-polyfill'; // es6 shim
import myUpload from 'vue-image-crop-upload/upload-2.vue';

export default {
    props:['avatar'],
    data() {
       return {
            show: false,
            params: {
                _token:Laravel.csrfToken,
                name: 'img',

                },
            headers: {
                smail: '*_~'
                },
            imgDataUrl: this.avatar // the datebase64 url of created image
        }
    },
    components: {
        'my-upload': myUpload
    },
    methods: {
        toggleShow() {
            this.show = !this.show;
        },
        /**
         * crop success
         *
         * [param] imgDataUrl
         * [param] field
         */
        cropSuccess(imgDataUrl, field){
            console.log('-------- crop success --------');
            this.imgDataUrl = imgDataUrl;
        },
        /**
         * upload success
         *
         * [param] jsonData  server api return data, already json encode
         * [param] field
         */
        cropUploadSuccess(response, field){
            console.log('-------- upload success --------');
           this.imgDataUrl = response.url;

            // 上傳成功後,影藏掉
            this.toggleShow();
        },
        /**
         * upload fail
         *
         * [param] status    server api return error status, like 500
         * [param] field
         */
        cropUploadFail(status, field){
            console.log('-------- upload fail --------');
            console.log(status);
            console.log('field: ' + field);
        }
    }
}
</script>

Avatar.vue 引入app.js文件中

// 設置頭像
Vue.component('avatar', require('./components/Avatar.vue'));

const app = new Vue({
    el: '#app'
});

在視圖文件 avatar.blade.php 中使用 avatar 組件

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">更換頭像</div>

                    <div class="panel-body">

                    <avatar avatar="{{ Auth::user()->avatar }}"></avatar>
                    </div>
                </div>
            </div>
        </div>
    </div>
@endsection

服務器的保存控制器UsersController.php方法:

/**
     * 頭像上傳保存到本地服務器
     */
    public function avatarUpload(Request $request)
    {
        // 獲取圖片文件對象
        $file = $request->file('img');

        // 文件名
        $filename = md5(time() . user()->id) . '.' . $file->getClientOriginalExtension();

        $file->move(public_path('avatars'), $filename);

        // 修改用戶的頭像
        // user()->avatar = asset(public_path('avatars/'.$filename));
        user()->avatar = '/avatars/'.$filename; // 相對路徑
        user()->save();

        return ['url' => user()->avatar];
    }

Github地址:https://github.com/dai-siki/v...

9、圖片上傳到七牛雲

七牛雲擴展包GitHub地址:laravel-filesystem-qiniu

1.安裝

$ composer require "overtrue/laravel-filesystem-qiniu"

2.配置

config/app.php 文件中配置:

'providers' => [
    // Other service providers...
    Overtrue\LaravelFilesystem\Qiniu\QiniuStorageServiceProvider::class,
],

config/filesystems.php 中配置:

'qiniu' => [
       'driver'     => 'qiniu',
       'access_key' => env('QINIU_ACCESS_KEY', 'xxxxxxxxxxxxxxxx'),
       'secret_key' => env('QINIU_SECRET_KEY', 'xxxxxxxxxxxxxxxx'),
       'bucket'     => env('QINIU_BUCKET', 'test'),
       'domain'     => env('QINIU_DOMAIN', 'xxx.clouddn.com'), // or host: https://xxxx.clouddn.com
    ],

3.具體用法:

/**
     * 頭像上傳保存到本地服務器
     */
    public function avatarUpload(Request $request)
    {
        // 獲取圖片文件對象
        $file = $request->file('img');

        /*
         * 本地存儲圖片
        // 文件名
        $filename = md5(time().user()->id) . '.' . $file->getClientOriginalExtension();

        // 將圖片保存到本地
        // $file->move(public_path('avatars'), $filename);

        // 修改用戶的頭像
        // user()->avatar = asset(public_path('avatars/'.$filename));
        user()->avatar = '/avatars/'.$filename; // 相對路徑
        */

        // 將圖片保存到七牛[20170405]
        $filename = 'avatars/' . md5(time().user()->id) . '.' . $file->getClientOriginalExtension();

        Storage::disk('qiniu')->writeStream($filename, fopen($file->getRealPath(), 'r'));
        user()->avatar = 'http://'.config('filesystems.disks.qiniu.domain') . '/' . $filename;

        user()->save();

        return ['url' => user()->avatar];
    }

重構提交數據的驗證

咱們須要對客戶端提交的數據進行驗證,驗證經過後才能入庫,以下邊的發表一篇文章爲例,一般的寫法是在store方法中獲取提交的數據,以後再經過規則驗證valigate,不過這裏咱們有一個更好的方法,那就是使用依賴注入

/**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        // $answer = $request->all();
        // dd($answer);

        // 驗證提交的數據
        $rules = [
            'title' => 'required|min:6|max:150',
            'body'  => 'required|min:40'
        ];

        // 自定義消息提示
        $messages = [
            'body.required' => "內容 不能爲空。",
            'body.min' => "內容 不能少於40個字符。",
        ];
        $this->validate($request, $rules, $messages);

        $data = [
            'title' => $request->get('title'),
            'body' => $request->get('body'),
            'user_id' => Auth::id(),
        ];
        $question = Question::create($data);

        flash("恭喜你,發佈成功!", "success");
        return redirect()->route('questions.show', [$question->id]);
    }

上邊的方法,是將驗證規則寫在store方法裏邊的,咱們能夠經過依賴注入對上邊的方法進行重構,先使用命令生成request。

php artisan make:request StoreQuestionRequest

將表單的驗證寫入用命令生成的Http\Requests\StoreQuestionRequest.php文件

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreQuestionRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Valigate messages
     *
     * @return array
     */
    public function messages()
    {
        return [
            'body.required' => "內容 不能爲空。",
            'body.min'      => "內容 不能少於40個字符。",
        ];
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title' => 'required|min:6|max:150',
            'body'  => 'required|min:40'
        ];
    }
}

將表單驗證注入到接收的參數:

/**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(StoreQuestionRequest $request)
    {
      
        // $this->validate($request, $rules, $messages);

        $data = [
            'title' => $request->get('title'),
            'body' => $request->get('body'),
            'user_id' => Auth::id(),
        ];
        $question = Question::create($data);

        flash("恭喜你,發佈成功!", "success");
        return redirect()->route('questions.show', [$question->id]);
    }

這個方法裏邊的參數store(StoreQuestionRequest $request)便可對傳遞過來的參數進行驗證,重構以後,咱們的store方法是否是簡潔了許多^_^

相關文章
相關標籤/搜索