20210414のvue.jsに関する記事は9件です。

意外と単純ではない TextBox が atom である理由

はじめに Dwango でニコニコ生放送のフロント開発を担当している @misuken です。 前回の記事 普遍的な atom と molecule の境界を意識したコンポーネント設計 では、 内包する構成要素が無ければ意味を成さないコンポーネントかどうか を焦点にすることで、 atom と molecule を普遍的に、どのプロジェクトでも共通した粒度として扱えるようになることを紹介しました。 今回はその記事の最後で挙げていた TextBox SelectBox ComboBox のもっと奥深い粒度の話を掘り下げていきたいと思います。 TextBox の粒度も単純ではない <input type="text" /> を出力するような TextBox というコンポーネントを作った場合、ほぼ 100% の人が atom として認識するでしょう。 しかし、ただのテキストボックスと言えどもそれより小さい粒度の物が存在しないとは言えません。 例えば Google の検索フォームの入力欄を見てみましょう。 右端のボタン二つは入力欄とは別に置かれているボタンであると言えるのですが、入力をクリアするボタンは、関心の対象や責務の境界から捉えても、テキストボックスに標準搭載された機能と言えないでしょうか? テキストボックスのクリアボタン テキストボックスのクリアボタンは、なぜテキストボックス標準搭載の機能と言えるのか。それは、以下のような理由からです。 クリアボタンの責務が完全にテキストボックス内で完結している 完全に閉じた責務であり、コンポーネント外で制御する必要がない コンポーネントを使用する側としてはクリアボタン制御が隠蔽されていてほしい テキストボックスの入力状況とボタンの表示が密接に関係している 空のときは非表示で、入力されると表示される テキストボックスを設置する全ての場所で要求される可能性がある クリアボタンがこれだけテキストボックスと密接な関係にあり、テキストボックスが無ければクリアボタンの存在意義がないとなれば、標準搭載されていないと毎回要求された場所に実装するのは明らかに面倒です。 これを裏付けるように Edge では <input type="text" /> に標準でクリアボタンが付いていたりします。 全てのブラウザで標準搭載されていないクリアボタン Edge では標準搭載されているテキストボックスのクリアボタンですが、残念ながら全てのブラウザで標準搭載されているわけではありません。 そうなると、検索フォームを作る際「入力欄にテキストを入力したら出現するクリアボタンを付けてください」という要求が来たとき、自力で実装する必要が出てきます。 すると、ただの atom だと思っていたコンポーネントでクリアボタンも出力する必要が出てきます。 <input type="text" class="text-box" /><button class="clear-button" /> ここで 内包する構成要素が無ければ意味を成さないコンポーネントかどうか という知見を持ち合わせていないと、「あれ、原子だったはずが、さらに分解できる要素が出てきて分子っぽくなったぞ、 atom と molecule どっちが正しいんだろう?」と迷うことになってしまいます。 知見を持ち合わせていれば、クリアボタンはオプションであって、それが無くても主体であるテキストボックスの意味を成していることから、明確に atom と断言できるわけです。 意外とリッチなテキストボックス クリアボタンは標準搭載されていないブラウザが多いのですが、 type 属性を変えると、ブラウザに実装されている様々な要素が現れます。(実装されているかはブラウザによります) 数値 <input type="number" /> スピンボタンが表示されます。 日付 <input type="date" /> 日付ピッカーが表示されます。 属性は粒度に影響を与えない 属性を変えただけでコンポーネントの粒度が変わってしまっては、それこそ収拾がつかなくなってしまうので、テキストボックスはどんなリッチな補助機能が付いたとしても TextBox を主体としている以上 atom であり続けるべきです。(あくまで TextBox の表現の違いでしかないため) TextBox という役割が atom であると捉えれば、これ以上分割できないことがわかります。 自作コンポーネントとの整合性 テキストボックスであれば、 <input type="text" /> を使って実装するのが当たり前ではありますが、 <input type="number" /> のスピンボタンのスタイルが気に入らないなど、ブラウザ標準では対応できないこともあるでしょう。 大抵は CSS で変更可能なように疑似要素が用意されているのですが、それでも対応できない場合もあります。 そのような場合は、同等の機能をコンポーネントとして自作するしかありません。 このような場合も、クリアボタンのときと同様に、 <input type="number" /> に対してボタン要素などを追加する必要が出てきます。 もし、単純に要素の数だけでコンポーネントの粒度を切り替えていたとしたら、 <input type="number" /> は atom だけど、自作スピンボタンを追加したほうのコンポーネントは molecule というように、全く同じ表示で全く同じ機能を有していながら粒度が違うことになってしまいます。 このように物理的な視点で粒度を捉えてしまうと、適切な粒度管理が行えなくなってしまうことがわかります。 粒度を物理で捉えない 粒度というと物理的な印象を受けますが、要素を物理的に捉えて粒度とすると破綻します。 これが粒度設計でハマりやすいポイントになっていのかもしれません。 BCD Design で言うところの Base つまり UI の型名で粒度を捉えられれば、普遍的な粒度を手に入れることが可能です。 そのため、コンポーネント名の末尾に安定して洗練された UI の型名を付けることが、コンポーネントの像をより明確にし、粒度が明確になることで依存関係も明確になるなど、様々な曖昧さを排除するメリットに繋がります。 このように、一切の主観を含まず正規化された結果は普遍であるため、プロジェクトを横断しても利用可能な長期的な資産となります。 さらに奥深い粒度の話 まだ SelectBox と ComboBox の話を書いていませんが、長くなったので今回はここまでにしておきます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Qiita管理システム

URL 非公開 システム概要 ・記事情報を取得し、一覧表示する ・記事の詳細情報を表示する ・記事の投稿が可能 使用ツール ・Vue.js(Vuex/Vue Router) ・CSS(Sass) ・XD ・Firebase Hosting ・axios(通信用ライブラリ) ・marked(マークダウン変換用) ・bootstrap-vue 使用API 参照元:https://qiita.com/api/v2/docs 記事情報取得API https://qiita.com/api/v2/users/*username*/items? 記事投稿API https://qiita.com/api/v2/items? 仕様 一覧 投稿した記事が全て表示されること タイトル・投稿日時が表示されること 詳細 選択した記事のタイトル・投稿ID・投稿日時が表示されること 詳細がマークダウンを変換して表示されること 記事投稿 タイトル・投稿内容を登録出来ること 投稿内容はマークダウン形式で入力 変換エリアにマークダウンを変換した結果が表示されること タイトル・投稿内容が必須(必須項目が未入力であれば投稿ボタンは非活性)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

⑩Vue.js & Laravel(認証機能の追加)

こちらは10本の記事で構成されています ①Vue.js & Laravel(環境構築) ②Vue.js & Laravel(CRUDシステムの準備) ③Vue.js & Laravel(Read...データベースからデータを取得) ④Vue.js & Laravel(Create...データベースにデータを保存) ⑤Vue.js & Laravel(Update…データベースのデータを更新) ⑥Vue.js & Laravel(Delete…データベースのデータを削除) ⑦Vue.js & Laravel(リアルなダミーデータを大量に挿入) ⑧Vue.js & Laravel(検索機能の実装) ⑨Vue.js & Laravel(ページャーの実装) ⑩Vue.js & Laravel(認証機能の実装) 【目標】認証機能を実装する 【手順】①ログインしていないユーザーをブロックする②APIでユーザー情報を取得し表示する ①ログインしていないユーザーをブロックする /routes/web.php <?php use Illuminate\Support\Facades\Route; Auth::routes(); + Route::get('/login', 'Auth\LoginController@showLoginForm')->name('login'); + Route::post('/login', 'Auth\LoginController@login'); + Route::get('/logout', 'Auth\LoginController@logout')->name('logout'); + Route::post('/logout', 'Auth\LoginController@logout', 'logout'); + Route::group(['middleware' => 'auth:web'], function () { Route::get('/', function () { return view('app'); }); + }); ②APIでユーザー情報を取得し表示する /resources/js/components/user/User.vue <template> <div class="taskComponent"> + 私の名前は<span>{{user.name}}</span><br> + メールアドレスは<span>{{user.email}}</span> + <br> + <br> + <a href="/logout">ログアウト</a> </div> </template> <script> export default { data() { return { + user:{} }; }, methods: { + getLoginUser() { + axios.get("/api/loginuser").then((res) => { + this.user = res.data; + }); + }, }, mounted() { + this.getLoginUser() }, }; </script> <style lang="scss" scoped> + span{ + color: red; + } </style> /routes/web.php <?php use Illuminate\Support\Facades\Route; Auth::routes(); Route::get('/login', 'Auth\LoginController@showLoginForm')->name('login'); Route::post('/login', 'Auth\LoginController@login'); Route::get('/logout', 'Auth\LoginController@logout')->name('logout'); Route::post('/logout', 'Auth\LoginController@logout', 'logout'); Route::group(['middleware' => 'auth:web'], function () { Route::get('/', function () { return view('app'); }); }); + Route::middleware('auth')->get('api/loginuser', 'UserController@loginuser'); $ php artisan make:controller UserController /app/Http/Controllers/UserController.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request; + use App\User; + use Auth; class UserController extends Controller { + public function loginuser() + { + $loginuser = Auth::user(); + return $loginuser; + } } 【達成】今回の目標「ページャーを実装する」が達成されました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

⑨Vue.js & Laravel(ページャー機能の追加)

こちらは10本の記事で構成されています ①Vue.js & Laravel(環境構築) ②Vue.js & Laravel(CRUDシステムの準備) ③Vue.js & Laravel(Read...データベースからデータを取得) ④Vue.js & Laravel(Create...データベースにデータを保存) ⑤Vue.js & Laravel(Update…データベースのデータを更新) ⑥Vue.js & Laravel(Delete…データベースのデータを削除) ⑦Vue.js & Laravel(リアルなダミーデータを大量に挿入) ⑧Vue.js & Laravel(検索機能の実装) ⑨Vue.js & Laravel(ページャーの実装) ⑩Vue.js & Laravel(認証機能の実装) 【目標】ページャーを実装する 【手順】①Vuetifyのインストール②フロントエンドの実装 ①Vuetifyのインストール $ npm install vuetify $ npm install @mdi/font -D /resources/js/app.js import VueRouter from 'vue-router'; + import Vuetify from 'vuetify'; + import '@mdi/font/css/materialdesignicons.css' + import 'vuetify/dist/vuetify.min.css'; require('./bootstrap'); window.Vue = require('vue'); + Vue.use(Vuetify); Vue.use(VueRouter); const router = new VueRouter({ routes: [ { path: '/task', name: 'task', component: () => import('./components/task/Task.vue'), }, { path: '/search', name: 'search', component: () => import('./components/search/Search.vue'), }, { path: '/user', name: 'user', component: () => import('./components/user/User.vue'), }, ] }); Vue.component('app-component', require('./components/AppComponent.vue').default); const app = new Vue({ el: '#app', router, + vuetify: new Vuetify() }); ②フロントエンドの実装 /resources/js/components/search/Search.vue <template> <div class="searchComponent"> <form @submit.prevent="taskSearch"> 緊急:<input v-model="search.emergency" type="checkbox"><br> 内容:<input v-model="search.content" type="text"> <button>search</button> </form> <hr> + <div v-show="isShow" class="pagination"> + <v-pagination v-model="nowPage" :length="maxPages" @input="getNumber"></v-pagination> + </div> <ul> <li v-for="(task, index) in tasks" :key="index"> 緊急:<input type="checkbox" v-model="task.emergency" disabled='disabled'><br> 内容:<span :class="{red:task.emergency}">{{task.content}}</span> </li> </ul> </div> </template> <script> export default { data() { return { + isShow:false, + nowPage:1, + maxPages:0, + itemsNum:1, + maxItems:5, + taskDatas:[], search: { content: "", emergency: false, }, tasks:[], }; }, methods: { taskSearch(){ axios.post("/api/task/search", this.search).then((res) => { - this.tasks = res.data; + this.taskDatas = res.data; + this.getNumber(1); + this.isShow = true; }); }, + getNumber(page){ + let maxNum = this.taskDatas.length; + this.maxPages = Math.ceil(maxNum / this.maxItems); + this.tasks.splice(0, this.tasks.length); + for(let i = 0; i < this.maxItems; i++){ + if(i + this.maxItems * (page - 1) < maxNum -1){ + this.tasks.push(this.taskDatas[i + this.maxItems * (page - 1)]); + } + } + }, }, }; </script> <style lang="scss" scoped> li{ list-style: none; margin-bottom: 15px; } .red{ color: red; } + .pagination{ + max-width: 500px; + margin-bottom: 15px; + nav ::v-deep .v-pagination{ + &__item{ + color: #000066; + border: 1px solid #000066; + &--active{ + color: white; + background-color: #000066; + } + } + &__navigation{ + border: 1px solid #000066; + .theme--light.v-icon{ + color: #000066; + } + &--disabled{ + opacity: 0.3; + } + } + } + } </style> 【達成】今回の目標「ページャーを実装する」が達成されました。 次回↓↓↓↓⑩Vue.js & Laravel(認証機能の実装)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

⑧Vue.js & Laravel(検索機能の追加)

こちらは10本の記事で構成されています ①Vue.js & Laravel(環境構築) ②Vue.js & Laravel(CRUDシステムの準備) ③Vue.js & Laravel(Read...データベースからデータを取得) ④Vue.js & Laravel(Create...データベースにデータを保存) ⑤Vue.js & Laravel(Update…データベースのデータを更新) ⑥Vue.js & Laravel(Delete…データベースのデータを削除) ⑦Vue.js & Laravel(リアルなダミーデータを大量に挿入) ⑧Vue.js & Laravel(検索機能の実装) ⑨Vue.js & Laravel(ページャーの実装) ⑩Vue.js & Laravel(認証機能の実装) 【目標】検索機能を追加する 【手順】①フロントエンドからAPIにリクエストする②APIからコントローラーにリクエストを送る③コントローラーからデータベースにリクエストを送る④レスポンスを画面に表示させる ①フロントエンドからAPIにリクエストする /resources/js/components/search/Search.vue <template> <div class="searchComponent"> + <form @submit.prevent="taskSearch"> + 緊急:<input v-model="search.emergency" type="checkbox"><br> + 内容:<input v-model="search.content" type="text"> + <button>search</button> + </form> </div> </template> <script> export default { data() { return { + search: { + content: "", + emergency: false, + }, }; }, methods: { + taskSearch(){ + axios.post("/api/task/search", this.search).then((res) => { + }); + } }, }; </script> <style lang="scss" scoped> + li{ + list-style: none; + margin-bottom: 15px; + } + .red{ + color: red; + } </style> ②APIからコントローラーにリクエストを送る /routes/api.php <?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::post('/task/create', 'TaskController@create'); Route::get('/task/read', 'TaskController@read'); Route::put('/task/update', 'TaskController@update'); Route::delete('/task/delete/{id}', 'TaskController@delete'); + Route::post('/task/search', 'TaskController@search'); ③コントローラーからデータベースにリクエストを送る /app/Http/Controllers/TaskController.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Task; class TaskController extends Controller { public function create(Request $request) { Task::create([ 'emergency' => $request->emergency, 'content' => $request->content, ]); } public function read() { $data = Task::get(); return $data; } public function update(Request $request) { Task::where("id", $request->id)->update([ "emergency" => $request->emergency, "content" => $request->content, ]); } public function delete($id) { Task::where("id", $id)->delete(); } + public function search(Request $request) + { + $query = Task::query() + ->orderBy('id', 'asc'); + + $query->where('emergency','=', $request->emergency); + if(isset($request->content)){ + $query->where('content','like', "%".$request->content."%"); + } + + $data = $query->get(); + return $data; + } } ④レスポンスを画面に表示させる /resources/js/components/search/Search.vue <template> <div class="searchComponent"> <form @submit.prevent="taskSearch"> 緊急:<input v-model="search.emergency" type="checkbox"><br> 内容:<input v-model="search.content" type="text"> <button>search</button> </form> + <hr> + <ul> + <li v-for="(task, index) in tasks" :key="index"> + 緊急:<input type="checkbox" v-model="task.emergency" disabled='disabled'><br> + 内容:<span :class="{red:task.emergency}">{{task.content}}</span> + </li> + </ul> </div> </template> <script> export default { data() { return { search: { content: "", emergency: false, }, + tasks:[], }; }, methods: { taskSearch(){ axios.post("/api/task/search", this.search).then((res) => { + this.tasks = res.data; }); } }, }; </script> <style lang="scss" scoped> li{ list-style: none; margin-bottom: 15px; } .red{ color: red; } </style> 【達成】今回の目標「検索機能を追加する」が達成されました。 次回↓↓↓↓⑨Vue.js & Laravel(ページャーの実装)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

⑦Vue.js & Laravel(Faker...ダミーデータの大量挿入)

こちらは10本の記事で構成されています ①Vue.js & Laravel(環境構築) ②Vue.js & Laravel(CRUDシステムの準備) ③Vue.js & Laravel(Read...データベースからデータを取得) ④Vue.js & Laravel(Create...データベースにデータを保存) ⑤Vue.js & Laravel(Update…データベースのデータを更新) ⑥Vue.js & Laravel(Delete…データベースのデータを削除) ⑦Vue.js & Laravel(リアルなダミーデータを大量に挿入) ⑧Vue.js & Laravel(検索機能の実装) ⑨Vue.js & Laravel(ページャーの実装) ⑩Vue.js & Laravel(認証機能の実装) 【目標】Fakerでリアルなダミーデータを作成する 【手順】①日本語に対応させる②Fakerを作成する③seederでfakerを実行する ①日本語に対応させる /config/app.php - 'faker_locale' => 'en_US', + 'faker_locale' => 'ja_JP', ②Fakerを作成する $ php artisan make:factory TaskFactory これで/database/factories/TaskFactory.phpが作成されました /database/factories/TaskFactory.php <?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ - use App\Model; + use App\Task; use Faker\Generator as Faker; - $factory->define(Model::class, function (Faker $faker) { + $factory->define(Task::class, function (Faker $faker) { return [ + 'emergency' => $faker->boolean, + 'content' => $faker->country."について調べる", ]; }); ③seederでfakerを実行する /database/seeds/TaskSeeder.php <?php use Illuminate\Database\Seeder; use App\Task; class TaskSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { - for ($i = 1; $i <= 10; $i++) { - Task::create([ - 'emergency' => $i%2, - 'content' => 'content' . $i, - ]); - } + factory(Task::class, 100)->create(); } } $ php artisan migrate:refresh --seed 【達成】今回の目標「Fakerでリアルなダミーデータを作成する」が達成されました。 次回↓↓↓↓⑧Vue.js & Laravel(検索機能の実装)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

⑥Vue.js & Laravel(Delete...データベースのデータを更新)

こちらは10本の記事で構成されています ①Vue.js & Laravel(環境構築) ②Vue.js & Laravel(CRUDシステムの準備) ③Vue.js & Laravel(Read...データベースからデータを取得) ④Vue.js & Laravel(Create...データベースにデータを保存) ⑤Vue.js & Laravel(Update…データベースのデータを更新) ⑥Vue.js & Laravel(Delete…データベースのデータを削除) ⑦Vue.js & Laravel(リアルなダミーデータを大量に挿入) ⑧Vue.js & Laravel(検索機能の実装) ⑨Vue.js & Laravel(ページャーの実装) ⑩Vue.js & Laravel(認証機能の実装) 【目標】APIでリクエストし、データを削除する 【手順】①フロントエンドからAPIにリクエストする②APIからコントローラーにリクエストを送る③コントローラーからモデルを通してデータベースにリクエストを送る ①フロントエンドからAPIにリクエストする /resources/js/components/task/Task.vue <template> <div class="taskComponent"> <form @submit.prevent="taskCreate"> 緊急:<input v-model="newtask.emergency" type="checkbox"><br> 内容:<input v-model="newtask.content" type="text"> <button>create</button> </form> <hr> <ul> <li v-for="(task, index) in tasks" :key="index"> 緊急:<input @change="taskUpdate(index)" type="checkbox" v-model="task.emergency"><br> 内容:<span v-if="!task.edit" :class="{red:task.emergency}">{{task.content}}</span> <input v-if="task.edit" v-model="task.content" type="text"> <button v-if="!task.edit" @click="task.edit = true">edit</button> <button v-if="task.edit" @click="taskUpdate(index)">update</button> + <button @click="taskDelete(task.id)">delete</button> </li> </ul> </div> </template> <script> export default { data() { return { newtask: { content: "", emergency: false, }, tasks:[], }; }, methods: { taskCreate() { if (this.newtask != "") { axios.post("/api/task/create", this.newtask).then((res) => { this.newtask.emergency = false; this.newtask.content = ""; this.taskRead(); }); } }, taskRead() { axios.get("/api/task/read").then((res) => { this.tasks = res.data; this.tasks.forEach((task) => { this.$set(task, "edit", false); }); }); }, taskUpdate(index) { this.tasks[index].edit = false; axios.put("/api/task/update", this.tasks[index]).then((res) => { this.taskRead(); }); }, + taskDelete(id) { + axios.delete("/api/task/delete/" + id).then((res) => { + this.taskRead(); + }); + }, }, mounted() { this.taskRead(); }, }; </script> <style lang="scss" scoped> li{ list-style: none; margin-bottom: 15px; } .red{ color: red; } </style> これで「①フロントエンドからAPIにリクエストする」が達成されました ②APIからコントローラーにリクエストを送る /routes/api.php <?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::post('/task/create', 'TaskController@create'); Route::get('/task/read', 'TaskController@read'); Route::put('/task/update', 'TaskController@update'); + Route::delete('/task/delete/{id}', 'TaskController@delete'); これで「②APIからコントローラーにリクエストを送る」が達成されました ③コントローラーからモデルを通してデータベースにリクエストを送る /app/Http/Controllers/TaskController.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Task; class TaskController extends Controller { public function create(Request $request) { Task::create([ 'emergency' => $request->emergency, 'content' => $request->content, ]); } public function read() { $data = Task::get(); return $data; } public function update(Request $request) { Task::where("id", $request->id)->update([ "emergency" => $request->emergency, "content" => $request->content, ]); } + public function delete($id) + { + Task::where("id", $id)->delete(); + } } これで「③コントローラーからデータベースにリクエストを送る」が達成されました 【達成】今回の目標「APIでリクエストし、データを削除する」が達成されました。 次回↓↓↓↓⑦Vue.js & Laravel(リアルなダミーデータを大量に挿入)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

⑥Vue.js & Laravel(Delete...データベースのデータを削除)

こちらは10本の記事で構成されています ①Vue.js & Laravel(環境構築) ②Vue.js & Laravel(CRUDシステムの準備) ③Vue.js & Laravel(Read...データベースからデータを取得) ④Vue.js & Laravel(Create...データベースにデータを保存) ⑤Vue.js & Laravel(Update…データベースのデータを更新) ⑥Vue.js & Laravel(Delete…データベースのデータを削除) ⑦Vue.js & Laravel(リアルなダミーデータを大量に挿入) ⑧Vue.js & Laravel(検索機能の実装) ⑨Vue.js & Laravel(ページャーの実装) ⑩Vue.js & Laravel(認証機能の実装) 【目標】APIでリクエストし、データを削除する 【手順】①フロントエンドからAPIにリクエストする②APIからコントローラーにリクエストを送る③コントローラーからモデルを通してデータベースにリクエストを送る ①フロントエンドからAPIにリクエストする /resources/js/components/task/Task.vue <template> <div class="taskComponent"> <form @submit.prevent="taskCreate"> 緊急:<input v-model="newtask.emergency" type="checkbox"><br> 内容:<input v-model="newtask.content" type="text"> <button>create</button> </form> <hr> <ul> <li v-for="(task, index) in tasks" :key="index"> 緊急:<input @change="taskUpdate(index)" type="checkbox" v-model="task.emergency"><br> 内容:<span v-if="!task.edit" :class="{red:task.emergency}">{{task.content}}</span> <input v-if="task.edit" v-model="task.content" type="text"> <button v-if="!task.edit" @click="task.edit = true">edit</button> <button v-if="task.edit" @click="taskUpdate(index)">update</button> + <button @click="taskDelete(task.id)">delete</button> </li> </ul> </div> </template> <script> export default { data() { return { newtask: { content: "", emergency: false, }, tasks:[], }; }, methods: { taskCreate() { if (this.newtask != "") { axios.post("/api/task/create", this.newtask).then((res) => { this.newtask.emergency = false; this.newtask.content = ""; this.taskRead(); }); } }, taskRead() { axios.get("/api/task/read").then((res) => { this.tasks = res.data; this.tasks.forEach((task) => { this.$set(task, "edit", false); }); }); }, taskUpdate(index) { this.tasks[index].edit = false; axios.put("/api/task/update", this.tasks[index]).then((res) => { this.taskRead(); }); }, + taskDelete(id) { + axios.delete("/api/task/delete/" + id).then((res) => { + this.taskRead(); + }); + }, }, mounted() { this.taskRead(); }, }; </script> <style lang="scss" scoped> li{ list-style: none; margin-bottom: 15px; } .red{ color: red; } </style> これで「①フロントエンドからAPIにリクエストする」が達成されました ②APIからコントローラーにリクエストを送る /routes/api.php <?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::post('/task/create', 'TaskController@create'); Route::get('/task/read', 'TaskController@read'); Route::put('/task/update', 'TaskController@update'); + Route::delete('/task/delete/{id}', 'TaskController@delete'); これで「②APIからコントローラーにリクエストを送る」が達成されました ③コントローラーからモデルを通してデータベースにリクエストを送る /app/Http/Controllers/TaskController.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Task; class TaskController extends Controller { public function create(Request $request) { Task::create([ 'emergency' => $request->emergency, 'content' => $request->content, ]); } public function read() { $data = Task::get(); return $data; } public function update(Request $request) { Task::where("id", $request->id)->update([ "emergency" => $request->emergency, "content" => $request->content, ]); } + public function delete($id) + { + Task::where("id", $id)->delete(); + } } これで「③コントローラーからデータベースにリクエストを送る」が達成されました 【達成】今回の目標「APIでリクエストし、データを削除する」が達成されました。 次回↓↓↓↓⑦Vue.js & Laravel(リアルなダミーデータを大量に挿入)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

⑤Vue.js & Laravel(Update...データベースのデータを更新)

こちらは10本の記事で構成されています ①Vue.js & Laravel(環境構築) ②Vue.js & Laravel(CRUDシステムの準備) ③Vue.js & Laravel(Read...データベースからデータを取得) ④Vue.js & Laravel(Create...データベースにデータを保存) ⑤Vue.js & Laravel(Update…データベースのデータを更新) ⑥Vue.js & Laravel(Delete…データベースのデータを削除) ⑦Vue.js & Laravel(リアルなダミーデータを大量に挿入) ⑧Vue.js & Laravel(検索機能の実装) ⑨Vue.js & Laravel(ページャーの実装) ⑩Vue.js & Laravel(認証機能の実装) 【目標】データベースにAPIでデータを送信し、更新する 【手順】①フロントエンドからAPIにリクエストする②APIからコントローラーにリクエストを送る③コントローラーからモデルを通しデータベースを更新する ①フロントエンドからAPIにリクエストする /resources/js/components/task/Task.vue <template> <div class="taskComponent"> <form @submit.prevent="taskCreate"> 緊急:<input v-model="newtask.emergency" type="checkbox"><br> 内容:<input v-model="newtask.content" type="text"> <button>create</button> </form> <hr> <ul> <li v-for="(task, index) in tasks" :key="index"> - 緊急:<input type="checkbox" v-model="task.emergency"><br> + 緊急:<input @change="taskUpdate(index)" type="checkbox" v-model="task.emergency"><br> - 内容:<span v-if="!task.edit" :class="{red:task.emergency}">{{task.content}}</span> + 内容:<span v-if="!task.edit" :class="{red:task.emergency}">{{task.content}}</span> + <input v-if="task.edit" v-model="task.content" type="text"> + <button v-if="!task.edit" @click="task.edit = true">edit</button> + <button v-if="task.edit" @click="taskUpdate(index)">update</button> </li> </ul> </div> </template> <script> export default { data() { return { newtask: { content: "", emergency: false, }, tasks:[], }; }, methods: { taskCreate() { if (this.newtask != "") { axios.post("/api/task/create", this.newtask).then((res) => { this.newtask.emergency = false; this.newtask.content = ""; this.taskRead(); }); } }, taskRead() { axios.get("/api/task/read").then((res) => { this.tasks = res.data; + this.tasks.forEach((task) => { + this.$set(task, "edit", false); + }); }); }, + taskUpdate(index) { + this.tasks[index].edit = false; + axios.put("/api/task/update", this.tasks[index]).then((res) => { + this.taskRead(); + }); + }, }, mounted() { this.taskRead(); }, }; </script> <style lang="scss" scoped> li{ list-style: none; margin-bottom: 15px; } .red{ color: red; } </style> これで「①フロントエンドからAPIにリクエストする」が達成されました ②APIからコントローラーにリクエストを送る /routes/api.php <?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; Route::post('/task/create', 'TaskController@create'); Route::get('/task/read', 'TaskController@read'); + Route::put('/task/update', 'TaskController@update'); これで「②APIからコントローラーにリクエストを送る」が達成されました ③コントローラーからモデルを通しデータベースを更新する /app/Http/Controllers/TaskController.php <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Task; class TaskController extends Controller { public function create(Request $request) { Task::create([ 'emergency' => $request->emergency, 'content' => $request->content, ]); } public function read() { $data = Task::get(); return $data; } + public function update(Request $request) + { + Task::where("id", $request->id)->update([ + "emergency" => $request->emergency, + "content" => $request->content, + ]); + } } これで「③コントローラーからモデルを通しデータベースを更新する」が達成されました 【達成】今回の目標「データベースにAPIでデータを送信し、更新する」が達成されました。 次回↓↓↓↓⑥Vue.js & Laravel(Delete…データベースのデータを削除)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む