import { defineComponent } from 'vue';
import { getStoreState, StateSetPayload, STATE_SET_METHOD_NAME } from '../store/StoreControl';
import { DataBinderInfo, EMPTY_DATA_BIND_INFO, resolvePath, DataBindInfoInjectedInstance } from './helper';
import { PROVIDE_DATA_BIND_INFO_NAME } from './StorePathMixin';
/**
* store 値をバインドする mixin。
*
* @remarks
*
* ### 概要
*
* - Store state の参照/設定を制御する。
* - dataPath, viewStatePath, vueState は、vue 機能の inject を利用し、上位コンポーネントから dataBindInfo として伝達する。
*
* ### 前提条件
*
* - store mutations に `setStoreState` を指定してあること(setStoreState は store state 編集を実施)。
*
* ### 使用方法
*
* - コンポーネントに mixin を組み込む。
* - プロパティ mId に値のキー情報を設定する。
*
* ### Mixin 詳細
*
* | No | vue type | name | value type | desc | remarks |
* | --: | -------- | -------------- | -------------- | ----------------------------------------------------------- | -------------------------------------------- |
* | 1 | props | mId | string | 項目を一意に指定する ID。Store 参照時のキーとして利用する。 | |
* | 2 | computed | parentInfo | DataBinderInfo | 上位から引き継がれた `DataBinderInfo`。 |
* | 3 | computed | dataId | string | parentInfo.dataPath + '.' + mId の値。 | |
* | 4 | computed | viewStateId | string | parentInfo.viewStatePath + '.' + mId の値。 | |
* | 5 | computed | storeData | any | dataId に一致した store の値を取得/設定。 | |
* | 6 | computed | storeViewState | any | viewStateId に一致した store の viewState を取得。 | 上位引継ぎは無し。viewStateId の値のみ取得。 |
* | 7 | computed | storeMethodName | string | storeData setter メソッドで `setStoreState` を実行するための文字列。変更した場合はオーバーライドする。 | 初期値は setStoreState とする |
*
* - 注意点
* - storeViewState では Store の自身のパスの viewState のみ取得する。`parentInfo.viewState()` を利用する場合は、計算プロパティを実装すること。
*
* @example
*
* ### 実装例
*
* ```vue
*
*
*
*
*
* ```
*/
export default defineComponent({
name: 'StoreBindMixin',
inject: {
dataBindInfo: {
from: PROVIDE_DATA_BIND_INFO_NAME,
default: () => EMPTY_DATA_BIND_INFO,
},
},
props: {
mId: {
type: String,
required: true,
},
},
computed: {
parentInfo(): DataBinderInfo {
return (this as unknown as DataBindInfoInjectedInstance).dataBindInfo;
},
dataId(): string {
return resolvePath(this.parentInfo.dataPath(), this.mId);
},
viewStateId(): string {
return resolvePath(this.parentInfo.viewStatePath(), this.mId);
},
storeMethodName(): string {
return STATE_SET_METHOD_NAME;
},
storeData: {
get() {
return getStoreState(this.$store.state, this.dataId);
},
set(newVal: unknown) {
this.$store.commit(this.storeMethodName, {
path: this.dataId,
value: newVal,
} as StateSetPayload);
},
},
storeViewState() {
return getStoreState(this.$store.state, this.viewStateId);
},
},
});