使用環境
vue: ^2.5.7
vuex: ^3.0.1
dayjs”: ^1.7.7
element-ui: ^2.4.8
この記事は下記の続きです。
Laravel + JWTAuth + Vue.js でAPIログイン認証の実装
Laravel + Vue.js にVuexを導入する
LaravelでCRUD APIを作成する
Laravel+Vue.js+VuexでフロントのCRUDを作成
完成イメージはこんな感じです。
ストアの作成
ストアから見ていきます。
tasksステートは実際はサーバーから受け取るデータなので実際は空ですが、データ構造は次のようになっています。
resources/js/store/modules/task.js
const state = { tasks: [ { id: 1, title: "はじめてのタスク", // タイトル state_id: 0, // 状態ID user_id: 1, // ユーザーID due_at: "2018-11-14 15:00:00", // 期日 created_at: "2018-10-02 14:28:19", // 作成日 updated_at: "2018-11-05 22:41:04" // 編集日 }, { ... } ], filterQuery: {} // 検索パラメータ };
今回は、テキスト入力でのtitle検索、セレクトボックスでのstate_idの検索、デイトピッカーでのcreated_atの検索をします。
ステートには検索情報を入れるためのfilterQueryを作成します。
次にミューテーションです。
引数を展開してステートに入れるだけの関数を作成します。
const mutations = { // ... setFilterQuery(state, filterQuery) { state.filterQuery = {...filterQuery}; } };
ストアの最後はゲッターです。
ここにフィルター処理を書きます。
登録日(Date)の処理に今回はDayjsというライブラリを使用します。
NPMでインストールしておきましょう。
npm install dayjs --save
詳細は下記記事もご覧ください。
軽量の日付操作JavaScriptライブラリ「Day.js」
import dayjs from 'dayjs'; const getters = { filteredTasks (state) { let data = state.tasks; // タイトルの検索 if (state.filterQuery.title !== "") { data = data.filter(function (row) { return row['title'].indexOf(state.filterQuery.title) !== -1; }); } // 状態の検索 if (state.filterQuery.state_id !== "") { data = data.filter(function (row) { return row['state_id'] === state.filterQuery.state_id; }); } // 作成日で検索 if (state.filterQuery.created_at !== null) { const queryData = dayjs(state.filterQuery.created_at).format('YYYY-MM-DD'); data = data.filter(function (row) { return queryData === dayjs(row.created_at).format('YYYY-MM-DD'); }); } return data; } };
titleは文字列検索なのでindexOf
を使用して文字列が含まれるか判定します。
state_idは配列番号での検索なので、単純に数値がマッチしているかです。
created_atに関しては今回は時間を除く日付だけで検索したいので、日付フォーマットして検索してます。
また Element UI を使用している場合、未入力はnullになるのでここだけ入力条件がnullになります。
検索条件が追加された場合でも基本このパターンで追記していくだけで大丈夫そうです。
今回は取得したデータの検索のみなので、アクションは使用しません。
コンポーネントの編集
作成したストアをコンポーネントで使用してみましょう。
data
にローカルでアクセスする用のfilterQuery
を作成します。
resources/js/components/pages/Task.vue
data() { return { filterQuery: { title: "", state_id: "", created_at: null }, status: [{ name: '未着手', color: '#999' },{ name: '実行中', color: '#E6A23C' }, { name: '完了', color: '#67C23A' }], } },
computed
に作成したゲッターメソッドを登録。
computed: { ...mapGetters('task', [ 'filteredTasks' ]), },
mounted
でsetFilterQuery
を実行して、filterQuery
の初期値が入るようにします。
mounted() { this.setFilterQuery(this.filterQuery); },
methods
にはテンプレートから実行されるhandleChangeQuery
を作成します。
ミューテーションで作成したsetFilterQuery
を実行するだけですね。
methods: { handleChangeQuery() { this.setFilterQuery(this.filterQuery); }, },
コンポーネントのテンプレート部分です。
Element UI を使用しているのでちょっと特殊ではありますが、基本的にはv-model
にfilterQuery
を指定して、@change
にhandleChangeQuery
を指定します。
<el-form :inline="true" class="search-form"> <el-form-item> <el-input v-model="filterQuery.title" placeholder="タイトル" @change="handleChangeQuery" clearable></el-input> </el-form-item> <el-form-item> <el-select v-model="filterQuery.state_id" placeholder="状態" @change="handleChangeQuery" clearable> <el-option v-for="(item, index) in status" :key="index" :label="item.name" :value="index"> </el-option> </el-select> </el-form-item> <el-form-item> <el-date-picker v-model="filterQuery.created_at" type="date" placeholder="登録日" @change="handleChangeQuery"> </el-date-picker> </el-form-item> </el-form>
最後にリスト表示している部分にゲッターのfilteredTasks
を指定します。
Element UI ではテーブルはel-table
です。:data
に指定します。
<el-table :data="filteredTasks" :row-key="row => row.id" border stripe>
ここまでのソースコードはGithubに載せてあります。
LaravelTodoSPA