頭の中は異空間

ものづくり中心

Vuexを使わないVueJSのstoreを自前で用意する

import { ref, reactive, readonly } from "vue";

export function useStore() {
  const items = reactive({ list: [] });
  let backupList = [];

  const auth0 = reactive({ auth: null });

  function setUser(auth) {
    auth0.auth = auth;
  }
  function getUser() {
    return auth0.auth;
  }

  // データリスト登録
  function setItem<T>(list: T[]) {
    items.list = ref(list);
    backupList = list.concat();
  }

  // リストにデータ追加
  function add<T>(item: T) {
    items.list.unshift(item);
    backupList.unshift(item);
  }

  // リストからデータ削除
  function remove(id: Number) {
    let _target = items.list.filter(_obj => _obj.id === id);
    let _removeIndex = items.list.indexOf(_target[0]);
    items.list.splice(_removeIndex, 1);

    _target = backupList.filter(_obj => _obj.id === id);
    _removeIndex = backupList.indexOf(_target[0]);
    backupList.splice(_removeIndex, 1);
  }

  // データ検索
  function search<T>(list: T[]) {
    restore();
    const _target_ids = list.map((_obj: Object) => { return _obj.id });
    list.map((_obj: object) => {
      const _target = items.list.filter(_item => !_target_ids.includes(_item.id));
      _target.map((_deleteTarget: Object) => {
        const _removeIndex = items.list.indexOf(_deleteTarget);
        items.list.splice(_removeIndex, 1);
      });
    });
  }

  // バックアップからリストを復元する
  function restore() {
    if (items.list.length === backupList.length) { return; }

    const length = items.list.length;
    backupList.map((_obj: Object) => {
      items.list.push(_obj);
    });
    for(let _i = 0;_i < length;_i++) {
      items.list.shift();
    }
  }

  // リストを空にする
  function allClear() {
    items.list.splice(0);
  }

  return { setUser, getUser, items: readonly(items), setItem, add, remove, search, restore, allClear };
};

auth0という変数を使っているが、これはauth0を利用する前提で、認証済みユーザをstoreにぶち込むつもりで作っている。
ユーザを入れずにデータリストのみを使う場合はsetUser, getUserの部分を削除すればいい
backupListはデータリストの復元のためだけに使うのでスコープ外には公開しない

使い方

// App.vueでprovideする
export default defineComponent({
  name: "App",
  components: { NavigationHeader, FooterInformation },
  setup() {
    const store = useStore();
    provide('datalist', store);
  }
});


// データリストを使いたいところでinject
const store = inject('datalist');