2016.11.06,中国海南?海口
见过很多同学对写
Laravel 本身对前端开发就提供了很多支持,5.3 更是直接引入了 Vue 这个目前最流行的轻量级前端框架,这篇文章使用一个完整实际案例来讲讲如何在项目中使用 Vue 的 Reactivity 特性和组件化系统,让前端开发和后端无缝的结合在一起,让开发过程更愉悦,而且代码的可复用性也更强。
准备工作
实现「发送短信验证码」这个业务是个很不错的拿来演示的实际案例,在大多数项目中也用得到,前端代码不复杂,但也不简单,后端部分也需要接触到如何集成第三方服务、请求验证、缓存、队列、日志等 Laravel 框架基础的一些功能,不过先不用想那么复杂,我们来一步一步来搭建就可以。
创建全新的 Laravel 5.3 应用
composer create-project --prefer-dist laravel/laravel demo
为了方便演示,使用 make:auth
快速创建一些基本的页面:
php artisan make:auth
开发需求
Good job!现在看到登录界面之后,你接收到的任务(需求)就是,在用户忘记密码的时候进行发送重置链接之前,需要进行 手机号码的验证
:
完成后的效果如下,是不是很简单,不过我们在后面还是有很多工作需要处理的:
去浏览一下文档中的前端开发入手 是个不错的起点,不过在这里我们使用yarn 来安装 npm 依赖包:
# 切换到项目根目录 yarn # 在开发的过程中运行 gulp watch
需要完成的任务列表:
- 添加
phone
字段到用户表; - 添加
POST /api/phone/code
的接口来处理验证码的发送; - 编写 Vue 前端组件;
- 将组件整合到页面当中;
- Done!
1. 添加 phone
字段到用户表;
运行下面的命令之前需要配置好数据库连接:
php artisan make:migration add_phone_to_users_table --table=users # 迁移文件 `xxxx_add_phone_to_users_table.php` 内容: public function up() { Schema::table('users', function (Blueprint $table) { // Only consider China $table->string('phone', 11)->unique()->nullable(); }); } public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('phone'); }); } php artisan migrate
2. 添加 POST /api/phone/code
的接口来处理验证码的发送;
在 routes\api.php
文件中添加路由:
Route::post('phone/code', 'ApiController@sendVerifyCode');
创建 API 响应控制器,发送验证码的 Job;
php artisan make:controller ApiController php artisan make:job SendVerifyCode
下面是代码示例:
文件 app\Controllers\ApiController.php
内容:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Jobs\SendVerifyCode; class ApiController extends Controller { public function sendVerifyCode(Request $request) { $this->validate($request, ['phone' => 'required|size:11|exists:users']); dispatch(new SendVerifyCode($request->phone)); return ['success' => true]; } }
文件 app\Jobs\SendVrifyCode.php
内容:
<?php namespace App\Jobs; use PhpSms; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; class SendVerifyCode implements ShouldQueue { use InteractsWithQueue, Queueable, SerializesModels; protected $phone; /** * Create a new job instance. * * @return void */ public function __construct($phone) { $this->phone = $phone; } /** * Execute the job. * * @return void */ public function handle() { // Generate 4 digit random code $code = str_random(4); // Push it to cache storage, expired time: 10 mins \Cache::put($this->phone, $code, 10); $content = "【XXXX】您的验证码是{$code}"; $templates = [ 'YunPian' => env('YUNPIAN_TEMPLATE_VERIFYCODE_ID', 'your_temp_id'), ]; $templateData = [ 'code' => $code ]; PhpSms::make()->to($this->phone) ->template($templates) ->data($templateData) ->content($content) ->send(); } }
使用了 PhpSms 这个扩展包和云片来完成短信发送的工作;
3. 编写 Vue 前端组件;
在 resources/assets/js/
目录下, Laravel 已经帮你添加了一些代码,引入了 Bootrap
和 Vue
这两个库,所以你需要处理的工作是在该目录下的 components
使用 Vue 的 单文件组件系统 组织代码,然后在 app.js
文件引入该组件就可以:
Vue.component('example', require('./components/Example.vue'));
让我们开始进入这篇文章的正题,在 resources/assets/js/components
文件下面新建文件 SendCodeField.vue
组件:
<template> <div class="form-group"> <div class="form-group" :class="{'has-error': errorPhone}"> <label for="phone" class="col-md-4 control-label">手机号码</label> <div class="col-md-4"> <input type="text" class="form-control" name="phone" v-model="phone" required> <span class="help-block" v-show="errorPhone"> <strong>{{errorPhone}}</strong> </span> </div> </div> <label for="code" class="col-md-4 control-label">验证码</label> <div class="col-md-2"> <input type="text" class="form-control" name="code" v-model="code" required> <span class="help-block" v-show="errorCode"> <strong>{{errorCode}}</strong> </span> </div> <div class="col-md-2"> <button type="button" class="btn btn-default" :class="{disabled: counter !== 0}" @click="sendCode"> 发送验证码 <span v-show="counter > 0">({{counter}})</span> </button> </div> </div> </template> <script > export default{ name: 'sendCodeField', props: [], data () { return { phone: null, code: null, counter: 0 } }, computed: { errorPhone () { if (this.phone == null || this.checkPhone(this.phone)) { return false } return '手机号码不正确!'; }, errorCode () { if (this.code == null || this.code.length == 4) { return false } return '4 位验证码' } }, methods: { startCount (value = 60) { this.counter = value var self = this var clock = setInterval(function () { if (self.counter === 0) { clearInterval(clock) return } self.counter -= 1 }, 1000) }, sendCode () { if (this.phone == null || this.counter > 0 || !this.checkPhone(this.phone)) { return } var self = this this.$http.post('/api/phone/code', {phone: this.phone}) .then(function (response) { self.startCount() }) .then(function (error) { console.log(error) }) }, checkPhone: function (phone) { return !!phone.match(/^(0|86|17951)?(13[0-9]|15[012356789]|17[0678]|18[0-9]|14[57])[0-9]{8}$/) } } } </script >
然后不要忘记在 app.js
中引入该组件:
Vue.component('send-code-field', require('./components/SendCodeField.vue'));
4. 将组件整合到页面当中;
现在我们就可以在程序到需要使用到该组件的地方,引入该组件就可以:
<form> <send-code-field></send-code-field> </form>
Conclusion!
把一些复杂的页面操作拆分成单独的、可复用、可定制样式(基于 Bootstrap)的 Vue 组件,慢慢的形成团队内部的代码库(当然也欢迎开源出来),灵活的搭配使用,会让开发效率和维护工作变的非常简单。
而且这样处理之后 Vue 组件不仅可以在单页面应用中使用,而且在传统的 Web 应用也可以灵活的复用。我最近还尝试使用 Vue 组件和
PS
这篇文章其实做成视频可能更好一点,这么长的文章估计也没多少人看,:smile: 不知道写 Laravel 项目的时候会考虑使用 Vue 组件吗 :question: