# ローディングと高さのアニメーション
# デモ
# 使用している主な機能
算出プロパティ computed 120ページ
ウォッチャ watch 128ページ
nextTick 143ページ
コンポーネント 146ページ
動的コンポーネント 185ページ
トランジション 194ページ
# ソースコード
<template>
<div class="example-loading example">
<p><button @click="loadContent" :disabled="!list.length">コンテンツをリロード</button></p>
<!-- ボーダー付きのラッパーレイヤー -->
<div class="flexbox-wrapper" :style="{height: height+'px'}">
<!-- トランジション & $refs.body -->
<ul class="flexbox-body" ref="body">
<li v-for="item in list" :key="item.id">
{{ item.name }} {{ item.price }}
</li>
</ul>
<transition>
<Loading v-if="!list.length"/>
</transition>
</div>
</div>
</template>
<script>
import axios from 'axios'
import Loading from './Loading.vue'
export default {
components: { Loading },
data() {
return {
height: 0,
list: []
}
},
// ウォッチャ
watch: {
list() {
// nextTick
this.$nextTick(() => {
// $refs
this.height = this.$refs.body.getBoundingClientRect().height
})
}
},
methods: {
loadContent() {
this.list = []
axios.get('/data/list.json').then(response => {
setTimeout(() => {
this.list = response.data
}, 1500)
})
}
},
created() {
this.loadContent()
}
}
</script>
<style scoped>
.flexbox-wrapper {
position: relative;
border: 2px solid #ccc;
border-radius: 4px;
overflow: hidden;
transition: height .4s;
min-height: 3em;
}
.flexbox-body {
margin: 0 0 0 24px;
padding: 16px;
}
/* トランジション用スタイル */
.v-enter-active, .v-leave-active {
transition: opacity .4s;
}
.v-enter, .v-leave-to {
opacity: 0;
}
</style>
<template>
<div class="before-load-content">
LOADING NOW
</div>
</template>
<style scoped>
.before-load-content {
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
color: #bbb;
}
</style>
# コメント
Katashin さんの vue-size-provider を利用すると、要素の高さを監視して簡単に高さのアニメーションを適用できます。
← モーダルウィンドウ 時間差トランジション →