Open2
【Vue3】CompositionAPIでGitHubのTodoリストCloneに挑戦した履歴
画面サイズの固定 & 部分スクロール
以下を実現する必要がある。
- ボートの領域の高さを100%に固定する
- 各TodoList領域をスクロールさせる
ボートの領域の高さを100%に固定する
- 子要素(各TodoList)内でスクロールを発生させるために、ボートの外枠となる部分が画面内の収まるように固定する必要がある。
- 外枠となる
todo-view__todo
にheight: 100vh
を指定。
<div class="todo-view__header" ref="header">
<div class="todo-view__title">
GitHub TODO Clone
</div>
</div>
<div class="todo-view__todo" v-bind:style="diffHeaderHeight">
<div class="todo-view__todo-list">
<div class="todo-view__todo-list__title">
Todo
</div>
<TodoList/>
</div>
<div class="todo-view__todo-list">
<div class="todo-view__todo-list__title">
InProgress
</div>
<TodoList/>
</div>
<div class="todo-view__todo-list">
<div class="todo-view__todo-list__title">
Done
</div>
<TodoList/>
</div>
</div>
.todo-view__todo {
height: 100vh;
display: flex;
padding-left: 30px;
padding-right: 30px;
border: 1px solid rgba(128, 128, 128, 0.817);
background-color: rgb(39, 43, 50);
}
しかし、これではヘッダー部分(todo-view__header)の高さが考慮されていないので、ヘッダー部の高さを画面の高さから除外した高さをボード部分の高さとしてvueからv-bind:styleで埋め込む方法を取った。
-
header
をrefとしてHTML側に埋め込む -
header
の高さをViewPortの割合として計算するheaderVhLoad()を作成 - onMounted時と画面のリサイズ時にheaderVhLoad()の実行とwatchを使ってdiffHeaderHeight変数を更新
- diffHeaderHeight変数をボード部分の高さにv-bind:styleで埋め込み
import { ref, onMounted, watch } from 'vue';
import TodoList from './TodoList.vue';
const header = ref(null);
const headerVhPercentage = ref(0.0);
const diffHeaderHeight = ref('height: 100vh');
const marginHeaderVh = 3;
watch(headerVhPercentage, (newValue) => {
const ret = Math.round(newValue*100);
console.log(ret);
diffHeaderHeight.value = `height: calc(100vh - ${ret}vh - ${marginHeaderVh}vh)`
})
const headerVhLoad = (): void => {
if (header.value) {
// calc header ViewPort HeightPercentage
const element = header.value as HTMLElement;
const headerHeight = element.offsetHeight;
const viewportHeight = window.innerHeight;
const percentage = headerHeight / viewportHeight;
headerVhPercentage.value = percentage;
}
}
onMounted(() => {
headerVhLoad();
window.addEventListener('resize', headerVhLoad);
})
各TodoList領域をスクロールさせる
先述で親要素のtodo-view__todo
の高さを固定したので、
todo-view__todo-list
にoverflow-y: auto
を指定して、親要素の高さを超えたらスクロールさせるようにする。
.todo-view__todo-list {
flex-grow: 1;
margin: 5px;
border: 1px solid rgba(128, 128, 128, 0.817);
overflow-y: auto;
display: flex;
flex-direction: column;
background-color: black;
border-radius: 3px;
}
コード全体(2023/05/20 時点)