はじめに
Deepblueでは、「キメタビ」という好きな観光地をピックアップし、最適なルートを提案するサービスを運営しています。その中で、ユーザがランダムに表示される観光地の写真を直感的に選択できるUIとして、カードスワイプできるTinder風のデザインを実装しました。
スマートフォンアプリ用の実装例、ライブラリは豊富にあるのですがWebでの実装例は少ないためLaravel + Vue での事例をご紹介します。
Laravel + Vueを利用する準備
まずは、Laravel + Vueの環境構築を行います。
今回はVueでSPAを作成する前提での環境です。
Laravelプロジェクトの作成
まずは、新規のLaravelプロジェクトを作成します。
任意の場所で下記コマンドを実行します。
composer create-project --prefer-dist laravel/laravel sample-project
cd sample-project
php artisan serve
http://127.0.0.1:8000
にアクセスし、ウェルカムページが表示されるか確認してください。
laravel/uiのインストール、vueを利用するための準備
(参考:https://github.com/laravel/ui )
composer require laravel/ui
php artisan ui vue
npm install
/node_modules
が作成されます。
gitignoreされているためコミットされないと思いますが、入ってない場合は.gitignoreに追加しましょう。
npm install --save vue-router
npm run dev
(参考: https://router.vuejs.org/ja/ )
最後にVue Routerというパッケージを追加して準備完了です。
npm run devすることで、フロントエンドのソースコードがビルドされます。
開発中はnpm run watchを実行しておくとソースコードの変更を監視して自動でビルドしてくれます。
補足
> @ watch /Users/yutaseto/sample-project
> mix watch
Additional dependencies must be installed. This will only take a moment.
Running: npm install vue-loader@^15.9.5 --save-dev --legacy-peer-deps
Finished. Please run Mix again.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ watch: mix watch
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ watch script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/hoge/.npm/_logs/2021-04-30T13_32_39_629Z-debug.log
というエラーが出る場合があります。その場合は上記のメッセージにあるように、
npm install vue-loader@^15.9.5 --save-dev --legacy-peer-deps
を実行しましょう。
Vur Routerの設定とページの作成
routes/web.php
use IlluminateSupportFacadesRoute;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/{any}', function () {
return view('app');
})->where('any', '.*');
resouces/views/app.blade.php (新規)
<head>
<meta charset="utf-8">
<meta name="csrf-token" content="{{ csrf_token() }}">
<link href="{{ mix('/css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script src="{{ mix('/js/app.js') }}" defer></script>
</body>
</html>
resources/js/components/SampleComponent.vue (新規)
<p>テストページ</p>
</template>
<script>
export default {}
</script>
resources/js/app.js
import Vue from 'vue';
import VueRouter from 'vue-router'
import SampleComponent from "./components/SampleComponent"
require('./bootstrap');
window.Vue = require('vue').default;
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'history',
routes: [{
path: '/',
name: index,
component: SampleComponent
}]
})
const app = new Vue({
el: '#app',
router
});
http:/127.0.0.1:8000
にアクセスして「テストページ」と表示されたらページ作成完了です。
npm run dev
もしくは、 npm run watch
を忘れないようにしましょう。
VueTinderのインストールとセットアップ
VueTinderをインストールします。
npmもしくはyarnでインストールできます。
npm install vue-tinder --save
# or
yarn add vue-tinder
インストールできたら、まずは公式ドキュメントに従って、まずはカードだけを表示させてみましょう。
公式ドキュメントではbingイメージを利用しています。
<div id="app">
<Tinder key-name="id" :queue.sync="queue" :offset-y="10" @submit="onSubmit">
<template slot-scope="scope">
<div
class="pic"
:style="{
'background-image': `url(https://cn.bing.com//th?id=OHR.${scope.data.id}_UHD.jpg&pid=hp&w=720&h=1280&rs=1&c=4&r=0)`
}"
/>
</template>
<img class="like-pointer" slot="like" src="/assets/like-txt.png">
<img class="nope-pointer" slot="nope" src="/assets/nope-txt.png">
<img class="super-pointer" slot="super" src="/assets/super-txt.png">
</Tinder>
</div>
</template>
bing.js
export default [
"AdelieBreeding_ZH-CN1750945258",
"BarcolanaTrieste_ZH-CN5745744257",
"RedRocksArches_ZH-CN5664546697",
"NationalDay70_ZH-CN1636316274",
"LofotenSurfing_ZH-CN5901239545",
"UgandaGorilla_ZH-CN5826117482",
"FeatherSerpent_ZH-CN5706017355",
"VancouverFall_ZH-CN9824386829",
"WallofPeace_ZH-CN5582031878",
"SanSebastianFilm_ZH-CN5506786379",
"CommonLoon_ZH-CN5437917206",
"SunbeamsForest_ZH-CN5358008117",
"StokePero_ZH-CN5293082939",
"Wachsenburg_ZH-CN5224299503",
"SurfboardRow_ZH-CN5154549470",
"ToothWalkingSeahorse_ZH-CN5089043566",
"midmoon_ZH-CN4973736313",
"MilkyWayCanyonlands_ZH-CN2363274510",
"DaintreeRiver_ZH-CN2284362798"
];
<img src="/images/rewind.png" @click="decide('rewind')" />
<img src="/images/nope.png" @click="decide('nope')" />
<img src="/images/love.png" @click="decide('like')" />
<img src="/images/info.png" />
この画像がなければエラーが出ます。
フリー素材などで探してみてください。
カードが表示されたら無事導入完了です!
次回はカスタマイズについてご説明します。
VueTinderでできることについて、キメタビもぜひご参考ください。