學習指東:使用 Laravel Jetstream

右手發表於2021-09-01

體驗了三天,過程很絲滑,結果很骨感:Laravel Jetstream 提供了兩種預設來實現,各有千秋。

安裝

在安裝時的選項:

  • 0:將選擇 Livewire,使用 blade 檢視渲染前臺的頁面,這個很傳統了YYDS;
  • 1:將選擇 Inertia,使用 vue 元件渲染前臺的頁面,實際上有一些小問題,具體內容在後面說明;

為了快速體驗,直接建立新專案:

# --jet 建立專案
laravel new laravel_jet1 --jet

#選擇 01,
Which Jetstream stack do you prefer?
  [0] livewire
  [1] inertia

#回車,預設不使用 team
Will your application use teams? (yes/no) [no]:

配置:

# 配置 .env,包括資料庫和郵件
MAIL_MAILER=smtp
MAIL_HOST=smtp.qq.com
MAIL_PORT=587
MAIL_USERNAME=demo@qq.com
MAIL_PASSWORD=授權碼
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=demo@qq.com

執行:

# 安裝 UI 依賴
# [0]livewire 需要此操作
# [1]inertia 安裝後自動執行,不過要根據實際的情況來判斷
npm i
npm run dev/prod

# 執行資料庫遷移,並啟動專案
php artisan migrate
php artisan serve

到這裡就能體驗使用者認證了,當然還要處理“郵件認證”。

郵件認證

兩種預設,只在“返回頁面”的寫法上有區別,其它的一樣:

# app/Models/User.php,繼承 MustVerifyEmail
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;

class User extends Authenticatable implements  MustVerifyEmail { }

新增“郵件認證”的路由,這裡“Email 認證通知”(的返回頁面)是 [0]livewire 的寫法:

# routes/web.php,新增一些路由來處理郵件認證
// Email 認證通知
Route::get('/email/verify', function (Request $request) {
    if (empty($request->user()->email_verified_at)) {
        return view('auth.verify-email');
    } else {
        return redirect()->route('dashboard');
    }
})->middleware('auth')->name('verification.notice');

// Email 認證處理
Route::get('/email/verify/{id}/{hash}', function (EmailVerificationRequest $request) {
    $request->fulfill();
    return redirect()->route('dashboard');
})->middleware(['auth', 'signed'])->name('verification.verify');

// 重新傳送 Email 認證郵件
Route::post('/email/verification-notification', function (Request $request) {
    $request->user()->sendEmailVerificationNotification();
    return back()->with('message', 'Verification link sent!');
})->middleware(['auth', 'throttle:6,1'])->name('verification.send');

[1]inertia 的寫法:

// Email 認證通知
Route::get('/email/verify', function (Request $request) {
    if (empty($request->user()->email_verified_at)) {
        return Inertia::render('Auth/VerifyEmail');
    } else {
        return redirect()->route('dashboard');
    }
})->middleware('auth')->name('verification.notice');

打完收工!

頁面

預設 [0]livewire 的頁面在 resources/views/下 。
預設 [1]inertia 的頁面在 resources/js/下:

  • Jetstream/:是封裝的元件;
  • Layout/:是佈局的元件;
  • Pages/:是頁面(的元件),通過 Inertia:render() 來渲染;

這裡出現兩個疑問:還要學習 inertia 框架?國際化咋搞?
呵呵,我是個戰鬥力 FIVE 的前端啊!不要慫,上去幹!

[1]inertia

國際化

首先,[1]inertia 用的是 vue,而 vue 處於 v3 的大跨越時期。這個 vue i18n 就有點小問題,不過很容易解決:

#安裝最新的版本
npm install vue-i18n@next 

用最新的版本就可以了,目前別用官方文件的 vue add i18n,會出問題。這 [1]inertia 用了 vue3,又不能切換 vue2 ,斷我後了啊。

#想了想還是貼出報錯:
 ERROR  Error: Cannot find module '@vue/cli-shared-utils'
Require stack:
- D:\test\laravel_jet1\node_modules\vue-cli-plugin-i18n\prompts.js
- D:\test\laravel_jet1\package.json
Error: Cannot find module '@vue/cli-shared-utils'
Require stack:
- D:\test\laravel_jet1\node_modules\vue-cli-plugin-i18n\prompts.js
- D:\test\laravel_jet1\package.json
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15)
    at Function.resolve (internal/modules/cjs/helpers.js:98:19)
    at module.exports (D:\test\laravel_jet1\node_modules\vue-cli-plugin-i18n\prompts.js:4:38)
    at invoke (C:\Users\Administrator\AppData\Roaming\npm\node_modules\@vue\cli\lib\invoke.js:74:25)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)

之後就簡單了:

#建立 resources/js/i18n.js
import { createI18n } from "vue-i18n";

const i18n = createI18n({
  locale: "zh", //預設顯示的語言
  messages: {
    zh: require("./Lang/zh"),
    en: require("./Lang/en"),
  },
});

export default i18n;
#建立 resources/js/Lang/zh.js
module.exports = {
  hello: "你好,世界!",
};
#建立 resources/js/Lang/en.js
module.exports = {
  hello: "Hello World.",
};
#修改 resources/js/app.js
import i18n from './i18n';

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => require(`./Pages/${name}.vue`),
    setup({ el, app, props, plugin }) {
        return createApp({ render: () => h(app, props) })
            .use(plugin)
            .use(i18n)
            .mixin({ methods: { route } })
            .mount(el);
    },
});

然後,直接使用:

{{ $t('hello') }}

訪問特別慢的問題

看了下 F12 發現是本地環境缺失某個 js 外掛:

#resources/views/app.blade.php
@env ('local')
    <script src="http://localhost:3000/browser-sync/browser-sync-client.js"></script>
@endenv

全域性搜了下,按照 vender/mobiledetect/mobiledetectlib/docs/CONTRIBUTING.md 操作就可以了:

npm i -g browser-sync
browser-sync start --s . --f . --port 3000 --reload-debounce 1500 --no-ui

一些文件

插個空,雙因子驗證是個啥?登入後會失效舊的?怎麼還有 google 身份驗證器?

You may retrieve this token from your phone’s Google Authenticator application.
您可以從手機的 Google 身份驗證器應用程式中檢索此令牌。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章