Vuexで検索条件を保持する

やりたいこと

検索条件を保持し、当該画面に戻ってきたときに、前回の検索条件を表示する。

コード例

Vuexで呼び出される処理を定義していく。
※細かいところは省略済み。

//ファイルパス:modules/novel/search.js
const state = {
  searchParameter: {
    title: '',
    writername: '',
    description: ''
  }
}

const getters = {
  getSearchParameter: state => state.searchParameter
}

const actions = {
  // 検索処理
  [NOVEL_SEARCH]: ({ commit }, param) => {
    return new Promise((resolve, reject) => {
      // 検索条件をstateに保存する処理を呼び出す(下記のcommitでmutationsのNOVEL_SEARCHが実行される)
      commit(NOVEL_SEARCH, param)
      novelRepository.get(searchParameterBuilder(param))
      .then(resp => {
        commit(NOVEL_SEARCH_SUCCESS, resp)
        resolve(resp)
      })
      .catch(err => {
        commit(NOVEL_SEARCH_ERROR)
        reject(err)
      })
    })
  }
}

const mutations = {
  [NOVEL_SEARCH]: (state, param) => {
    state.searchParameter = param
  }
}

export default {
  state,
  getters,
  actions,
  mutations
}
import { createStore } from 'vuex'
import novelSearch from './modules/novel/search'

export default createStore({
  modules: {
    novelSearch
  }
})

vueファイルから以下の通り呼び出して、使用する。(記事の都合上、分けて記載しているけど、本来1つのファイル)

<script setup>
import { reactive, computed } from 'vue'
import { useStore } from 'vuex'
import { useI18n } from 'vue-i18n'
import { ElMessage, ElMessageBox } from 'element-plus'

const store = useStore()
const { t } = useI18n()

// Vuexに保持されている検索条件を読み込む
const searchParameter = computed(() => store.getters.getSearchParameter)

const state = reactive({
  title: searchParameter.value.title,
  writername: searchParameter.value.writername,
  description: searchParameter.value.description
})

function search() {
  const { title, writername, description } = state
  // 検索処理を実行する(search.jsのactionsのNOVEL_SEARCHが実行される)
  store.dispatch(NOVEL_SEARCH, { title, writername, description }).catch(error => {
    ElMessage({
      message: error,
      grouping: true,
      type: 'error'
    })
  })
}
</script>
<template>
  <div class="novel-search">
    <el-card class="box-card box-card-wrapper">
      <el-row class="row-wrapper">
        <el-col
          class="col-wrapper"
          :span="6"
        >
          <el-input
            :placeholder="$t('title')"
            v-model="state.title"
            clearable
          />
        </el-col>

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です