コンポーネント内からhtmlにdata属性を操作したいとき
例えば、モーダルを表示する間だけhtml,bodyのスクロールをやめたい時などにクラスを追加したりdata属性をボタンの押下などで変化させるときの方法でつまづいたので備忘録その2。
composables
にtsファイルを作成、その中でuseStateを使用した処理を行い、コンポーネント内のモーダル開閉処理時に状態を変更をuseStateを介して行うとともに、useHeadのhtmlAttrsなどで使用している変数への変更の反映をwatchEffect
の中で行うことで状態変化を描画上も反映、視認確認できるようになりました。
composables内のtsファイル例(単純にフラグをbooleanで切り替え)
import { ref } from "vue";
type ModalFlag = {
value: boolean
}
export const modalOpen = (modalFlag:ModalFlag) => () => {
modalFlag.value = true;
return true;
}
export const modalClose = (modalFlag:ModalFlag) => () => {
modalFlag.value = false;
return false;
}
export const modalChangeStart = (modalFlag:ModalFlag) => () => {
modalFlag.value = false;
return false;
}
export const modalChangeEnd = (modalFlag:ModalFlag) => () => {
modalFlag.value = true;
return true;
}
export const useModalStatus = () => {
const modalFlag = useState('modalFlag', () => ref(false))
return {
modalFlag: readonly(modalFlag),
modalOpen: modalOpen(modalFlag),
modalClose: modalClose(modalFlag),
modalChangeStart: modalChangeStart(modalFlag),
modalChangeEnd: modalChangeEnd(modalFlag),
}
};
コンポーネント内の処理例(data-overflowで対応)
<script setup lang="ts">
import { ref, watch, watchEffect } from "vue";
let flag = ref(false);
... ##省略
... ##省略ここまで
// モーダル表示処理例
const showModal = () => {
modalOpen();
watchEffect(() => {
// useHead htmlAttersで使用している変数flagに反映
flag.value = modalFlag.value;
});
}
... ##省略
... ##省略ここまで
useHead({
htmlAttrs:{
'data-overflow': flag,
},
});
</script>
実際は写真の画像をリストから取得・反映などの処理でもっと複雑なのですが、モーダルの表示とそれに合わせたhtmlタグへのdata属性の反映は上記のような記載で対応できました。
本当はコンポーネントではなく、ページ毎やレイアウトファイル上で状態を管理できるようにしたほうがよいのですが、ひとまずコンポーネント単一で処理が完結できるようまとめて実装しました。