在這一篇示例教程中,我們將會構(gòu)建一個類似 Twitter 的 Web 應(yīng)用。我們將使用到 Laravel 5.6 和 Vue.js,并且在 Vue.js 中定義一些組件,此外,還會使用 Axios 來發(fā)送網(wǎng)絡(luò)請求。當然,篇幅有限,我們不可能開發(fā)一個完整的 Twitter 應(yīng)用,而是實現(xiàn)一個簡化版:用戶可以發(fā)送 Tweet 并在自己的時間線中看到,可以關(guān)注或取消關(guān)注其他用戶,如果關(guān)注了其他用戶,那么也可以看到關(guān)注用戶發(fā)布的 Tweet。麻雀雖小,五臟俱全,希望大家可以通過這個簡單的應(yīng)用學(xué)會 Laravel 和 Vue.js 的基礎(chǔ)用法。
注:這是一篇翻譯文章,你可以將 Twitter 對標國內(nèi)新浪微博,一條 Tweet 就是一條微博信息。
安裝配置 Laravel
首先,我們需要安裝一個新的 Laravel 應(yīng)用(也可以通過 Composer 安裝,看個人喜好):
laravel?new?laratwitter
進入該項目根目錄,安裝前端依賴:
npm?install
接下來,修改?.env
?中數(shù)據(jù)庫相關(guān)配置符合本地環(huán)境,然后通過如下命令生成用戶認證腳手架代碼:
php?artisan?make:auth
運行如下命令生成相關(guān)數(shù)據(jù)表:
php?artisan?migrate
接下來配置下 Web 服務(wù)器(使用 Valet 的話略過),我這里配置的域名是?laratwitter.test
,配置完成后重啟下 Web 服務(wù)器,然后通過?http://laratwitter.test/register
?注冊一個新用戶:
接下來編輯?resoureces >> views >> home.blade.php
?文件:
@extends('layouts.app') @section('content') <div?class="container"> ????<div?class="row?justify-content-center"> ????????<div?class="col-md-4"> ????????????Tweet?表單 ????????</div> ????????<div?class="col-md-8"> ???????????時間線 ????????</div> ????</div> </div> @endsection
新注冊用戶登錄后就能在新的 Home 頁看到變更后的效果了。
創(chuàng)建一個 Tweet 表單
我們使用 Vue.js 來完成表單創(chuàng)建,首先到?resources >> assets >> js >> components
?目錄下新增一個?FormComponent.vue
?文件:
//?FormComponent.vue <template> ????<div?class="col-md-4"> ????????<form> ????????????<div?class="form-group"> ????????????????<textarea? ????????????????????class="form-control"? ????????????????????rows="8"?cols="8"? ????????????????????maxlength="130"? ????????????????????required> ????????????????</textarea> ????????????</div> ????????????<div?class="form-group"> ????????????????<button?class="btn?btn-primary"> ????????????????????發(fā)送 ????????????????</button> ????????????</div> ????????</form>???????? ????</div> </template> <script> export?default?{ } </script>
然后在?resources >> assets >> js >> app.js
?中導(dǎo)入這個組件:
//?app.js require('./bootstrap'); window.Vue?=?require('vue'); Vue.component('form-component',?require('./components/FormComponent.vue')); const?app?=?new?Vue({ ????el:?'#app' });
最后在?home.blade.php
?中使用這個組件:
@extends('layouts.app') @section('content') <div?class="container"> ????<div?class="row?justify-content-center"> ???????<form-component></form-component> ????????<div?class="col-md-8"> ????????????TimeLines ????????</div> ????</div> </div> @endsection
為了監(jiān)聽前端資源變動,可以在項目根目錄下運行如下命令監(jiān)聽前端資源變動并實時編譯:
npm?run?watch
這樣,刷新?http://laratwitter.test/home
?頁面就可以看到變更后的效果了:
創(chuàng)建 Post 模型類及對應(yīng)數(shù)據(jù)庫遷移文件
下面我們來實現(xiàn)表單提交保存操作,首先創(chuàng)建一個模型類及對應(yīng)數(shù)據(jù)庫遷移文件:
php?artisan?make:model?Post?-m
編寫剛生成的數(shù)據(jù)庫遷移文件?create_posts_table.php
:
//?create_posts_table public?function?up() { ???Schema::create('posts',?function?(Blueprint?$table)?{ ???????$table->increments('id'); ???????$table->integer('user_id')->unsigned(); ???????$table->string('body',?140); ???????$table->timestamps(); ???????$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); ????}); }
運行數(shù)據(jù)庫遷移命令:
php?artisan?migrate
現(xiàn)在可以在數(shù)據(jù)庫中看到剛創(chuàng)建的?posts
?數(shù)據(jù)表了。
接下來創(chuàng)建控制器?PostController
:
php?artisan?make:controller?PostController
定義關(guān)聯(lián)關(guān)系
在?User
?模型類中,我們需要定義一個關(guān)聯(lián)方法建立?Post
?模型和?User
?模型之間的關(guān)聯(lián)關(guān)系(一對多):
public?function?posts() { ???return?$this->hasMany(Post::class); }
相應(yīng)地,在?Post
?模型類中,也要定義與?User
?模型的關(guān)聯(lián)關(guān)系:
public?function?user() { ???return?$this->belongsTo(User::class); }
在數(shù)據(jù)庫中保存 Tweet
前面提到我們將通過?axios
?庫來發(fā)送 POST 請求到 Laravel 后端服務(wù)器,這個庫在我們運行?npm install
?命令的時候已經(jīng)安裝好了,在開始處理請求發(fā)送與處理之前,我們先來定義請求路由,在?routes >> web.php
?文件中新增一個路由定義如下:
Route::post('tweet/save',?'PostController@store');
此外,還需要定義?Post
?模型類的?$fillable
?屬性來避免批量賦值異常:
protected?$fillable?=?['user_id',?'body'];
最后要做的準備工作就是到?PostController.php
?中定義?store
?方法:
public?function?store(Request?$request,?Post?$post) { ????$newPost?=?$request->user()->posts()->create([ ????????'body'?=>?$request->get('body') ????]); ????return?response()->json($post->with('user')->find($newPost->id)); }
我們使用了關(guān)聯(lián)關(guān)系來保存 Post 數(shù)據(jù),它會自動將當前登錄用戶的?id
?作為保存 Post 的?user_id
?字段。
后端邏輯實現(xiàn)之后,接下來需要使用?axios
?庫類發(fā)送 POST 請求,我們將相應(yīng)邏輯寫到?FormComponent.vue
?組件中:
//?FormComponent.vue <template> ????<div?class="col-md-4"> ????????<form?@submit.prevent="saveTweet"> ????????????<div?class="form-group"> ????????????????<textarea? ????????????????????class="form-control"? ????????????????????rows="8"?cols="8"? ????????????????????maxlength="130" ????????????????????v-model="body" ????????????????????required> ????????????????</textarea> ????????????</div> ????????????<div?class="form-group"> ????????????????<button?class="btn?btn-primary"> ????????????????????Tweet ????????????????</button> ????????????</div> ????????</form>???????? ????</div> </template> <script> export?default?{ ????data()?{ ????????return?{ ????????????body:?'' ????????} ????}, ????methods:?{ ????????saveTweet()?{ ????????????axios.post('/tweet/save',?{body:?this.body}).then(res?=>?{ ????????????????console.log(res.data); ????????????}).catch(e?=>?{ ????????????????console.log(e); ????????????}); ????????} ????} } </script>
CSRF_TOKEN
?會默認包含到每個 POST 請求,所以不必手動添加。現(xiàn)在,如果一切正常工作的話,你就可以成功保存 Post 數(shù)據(jù)并在響應(yīng)中獲取到 Post 對象及其關(guān)聯(lián)用戶:
創(chuàng)建一個 Vue 事件
要想在前端顯示所有 Tweet,首先需要將它們顯示到時間線中,為此,我們需要創(chuàng)建一個事件。注意,這里不是要通過刷新頁面來獲取所有 Tweet,而是當我們添加一條新的 Tweet 時,在不刷新頁面的情況下在用戶時間線中顯示這條 Tweet。
為了實現(xiàn)這個功能,需要創(chuàng)建一個事件并觸發(fā)這個事件,我們通過時間線組件來監(jiān)聽事件觸發(fā)并基于該事件更新 UI。可以通過?Vuex?來實現(xiàn)該功能,但是現(xiàn)在,我們不想要深入存儲和動作,只想將事情保持簡單。
在?resources >> assets >> js
?目錄下創(chuàng)建一個名為?event.js
?的文件,并編寫代碼如下:
//?event.js import?Vue?from?'vue'; export?default?new?Vue();
然后將該文件導(dǎo)入?FormComponent.vue
:
//?FormComponent.vue <template> ????<div?class="col-md-4"> ????????<form?@submit.prevent="saveTweet"> ????????????<div?class="form-group"> ????????????????<textarea? ????????????????????class="form-control"? ????????????????????rows="8"?cols="8"? ????????????????????maxlength="130" ????????????????????v-model="body" ????????????????????required> ????????????????</textarea> ????????????</div> ????????????<div?class="form-group"> ????????????????<button?class="btn?btn-primary"> ????????????????????Tweet ????????????????</button> ????????????</div> ????????</form>???????? ????</div> </template> <script> import?Event?from?'../event.js'; export?default?{ ????data()?{ ????????return?{ ????????????body:?'', ????????????postData:?{} ????????} ????}, ????methods:?{ ????????saveTweet()?{ ????????????axios.post('/tweet/save',?{body:?this.body}).then(res?=>?{ ????????????????this.postData?=?res.data; ????????????????Event.$emit('added_tweet',?this.postData); ????????????}).catch(e?=>?{ ????????????????console.log(e); ????????????}); ????????????this.body?=?''; ????????} ????} } </script>
這樣,當新提交數(shù)據(jù)被保存后,就可以觸發(fā)包含保存的 Tweet 和用戶信息的事件,監(jiān)聽該事件的監(jiān)聽器就可以捕獲數(shù)據(jù)并更新 UI。
創(chuàng)建時間線組件
接下來,我們來定義監(jiān)聽 Tweet 發(fā)送成功事件的監(jiān)聽器。
在?resources >> assets >> js >> components
?目錄下新增一個?TimelineComponent.vue
?組件,編寫該組件代碼如下:
//?TimelineComponent.vue <template> ????<div?class="col-md-8?posts"> ????????<p?v-if="!posts.length">No?posts</p> ????????<div?class="media"?v-for="post?in?posts"?:key="post.id"> ????????????<img?class="mr-3"?/> ????????????<div?class="media-body"> ????????????????<div?class="mt-3"> ????????????????????<a?href="#">{{?post.user.name?}}</a> ????????????????</div> ????????????????<p>{{?post.body?}}</p> ????????????</div> ????????</div> ????</div> </template> <script> import?Event?from?'../event.js'; export?default?{ ????data()?{ ????????return?{ ????????????posts:?[], ????????????post:?{} ????????} ????}, ????mounted()?{ ????????Event.$on('added_tweet',?(post)?=>?{ ????????????this.posts.unshift(post); ????????}); ????} } </script>
這里我們定義了一個監(jiān)聽?added_tweet
?事件的監(jiān)聽器,當該事件被觸發(fā)后,就可以執(zhí)行相應(yīng)的方法將數(shù)據(jù)渲染到時間線組件中。
和?FormComponent.vue
?組件一樣,在?app.js
?中注冊這個組件:
Vue.component('timeline-component',?require('./components/TimelineComponent.vue'));
我們專注高端建站,小程序開發(fā)、軟件系統(tǒng)定制開發(fā)、BUG修復(fù)、物聯(lián)網(wǎng)開發(fā)、各類API接口對接開發(fā)等。十余年開發(fā)經(jīng)驗,每一個項目承諾做到滿意為止,多一次對比,一定讓您多一份收獲!