再描画が必要なケース
- データが更新されても、バインドしているコンポーネントのサイズが最適化されない
- 画面レイアウトの動的変更に最適化されない
具体例
- データを更新して文字列が長くなったが、Textareaのサイズが変わらず、文字切れが発生する
- 隣り合うコンポーネントの動的表示/非表示により、もう一方のコンポーネントの幅が伸縮されたが高さが変わらないため、文字切れまたは余分な空白が発生する。
対応方法
- コンポーネントのkey属性を変更する
Sample.vue
<template>
<v-textarea
:value="Value"
:key="RenderKey"
>
</v-textarea>
</template>
<script lang="ts">
import Vue from 'vue';
import { Getter } from 'vuex-class';
const namespace: string = 'sample';
export default class Sample extends Vue {
@Getter('Value', {namespace}) public Value!: string;
@Getter('RenderKey', {namespace}) public RenderKey!: number;
}
</script>
types.ts
export interface SampleState {
Value: string;
RenderKey: number;
}
index.ts
import { Module } from 'vuex';
import { actions } from './actions';
import { mutations } from './mutations';
import { getters } from './getters';
import { SampleState } from './types';
import { RootState } from '@/store/types';
const namespaced: boolean = true;
export const state: SampleState = {
RenderKey: Math.random(),
Value: '',
};
export const sample: Module<SampleState, RootState> = {
namespaced,
state,
actions,
mutations,
getters,
};
getters.ts
import { GetterTree } from 'vuex';
import { SampleState } from './types';
import { RootState } from '@/store/types';
export const getters: GetterTree<SampleState, RootState> = {
Value(state: SampleState): string {
return state.Value;
},
RenderKey(state: SampleState): number {
return state.RenderKey;
},
};
actions.ts
import { ActionTree } from 'vuex';
import { SampleState } from './types';
import { RootState } from '@/store/types';
import axios from 'axios';
export const actions: ActionTree<SampleState, RootState> = {
SetTextValue({commit}, payload: string) {
axios({
method: 'POST',
url: "https://xxx",
data: payload,
})
.then((res) => {
commit('SetTextValue', res.data.value);
commit('ReRenderTextArea');
}).catch((err) => {
}).finally(() => {
});
},
};
mutations.ts
import { MutationTree } from 'vuex';
import { SampleState } from './types';
export const mutations: MutationTree<SampleState> = {
SetTextValue(state, payload: string) {
state.Value = payload;
},
ReRenderTextArea(state) {
state.RenderKey = Math.random(); //または何らかの一意の値
},
};
参考
感想
- key属性は重要