
Vue.js ルーティング演習問題
基本概念まとめ 1. ルーティングの基本設定 2. ナビゲーションガード 3. 動的ルーティング 演習問題(全24問) 初級問題(6問) 基本ルーティング ナビ […]
<!-- デフォルトスロット -->
<slot></slot>
<!-- 名前付きスロット -->
<slot name="header"></slot>
<!-- スコープ付きスロット -->
<slot :item="item"></slot>
<!-- 親コンポーネント -->
<ChildComponent>
<template v-slot:header>
<h1>ヘッダー内容</h1>
</template>
メインコンテンツ
</ChildComponent>
:is
属性で動的にコンポーネントを切り替えactivated
/deactivated
が使用可能に
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
<!-- ChildComponent.vue -->
<template>
<div class="child">
<slot>デフォルトの表示内容</slot>
</div>
</template>
<!-- ParentComponent.vue -->
<template>
<ChildComponent>
親から渡すコンテンツ
</ChildComponent>
</template>
<!-- CardComponent.vue -->
<template>
<div class="card">
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
</template>
<!-- ParentComponent.vue -->
<template>
<CardComponent>
<template v-slot:header>
<h2>カードタイトル</h2>
</template>
メインコンテンツ
<template v-slot:footer>
<button>詳細</button>
</template>
</CardComponent>
</template>
<!-- AlertComponent.vue -->
<template>
<div class="alert">
<slot>
<p>デフォルトの警告メッセージ</p>
</slot>
</div>
</template>
<template>
<component :is="currentComponent"></component>
<button @click="toggleComponent">切り替え</button>
</template>
<script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
export default {
data() {
return {
currentComponent: 'ComponentA'
}
},
components: { ComponentA, ComponentB },
methods: {
toggleComponent() {
this.currentComponent = this.currentComponent === 'ComponentA'
? 'ComponentB'
: 'ComponentA'
}
}
}
</script>
<template>
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
</template>
<template>
<div>
<button
v-for="tab in tabs"
:key="tab"
@click="currentTab = tab"
>
{{ tab }}
</button>
<keep-alive>
<component :is="currentTab"></component>
</keep-alive>
</div>
</template>
<script>
export default {
data() {
return {
tabs: ['Home', 'About', 'Contact'],
currentTab: 'Home'
}
},
components: {
Home, About, Contact
}
}
</script>
<!-- UserList.vue -->
<template>
<ul>
<li v-for="user in users" :key="user.id">
<slot :user="user">{{ user.name }}</slot>
</li>
</ul>
</template>
<script>
export default {
data() {
return {
users: [
{ id: 1, name: '山田太郎', age: 28 },
{ id: 2, name: '佐藤花子', age: 32 }
]
}
}
}
</script>
<!-- ParentComponent.vue -->
<template>
<UserList v-slot="{ user }">
{{ user.name }} ({{ user.age }}歳)
</UserList>
</template>
<!-- DynamicSlot.vue -->
<template>
<div>
<slot :name="slotName"></slot>
</div>
</template>
<script>
export default {
props: {
slotName: {
type: String,
default: 'default'
}
}
}
</script>
<!-- ParentComponent.vue -->
<template>
<DynamicSlot :slot-name="currentSlot">
<template #[currentSlot]>
動的スロットコンテンツ
</template>
</DynamicSlot>
</template>
<template>
<CardComponent>
<template #header>
<h2>省略記法</h2>
</template>
<template #default>
メインコンテンツ
</template>
<template #footer>
<button>OK</button>
</template>
</CardComponent>
</template>
<template>
<div>
<slot :data="items" :load="loadData"></slot>
</div>
</template>
<script>
export default {
data() {
return {
items: []
}
},
methods: {
async loadData() {
this.items = await fetchData()
}
}
}
</script>
<template>
<table>
<thead>
<slot name="header" :columns="columns"></slot>
</thead>
<tbody>
<tr v-for="item in data" :key="item.id">
<slot name="body" :item="item"></slot>
</tr>
</tbody>
</table>
</template>
<template>
<div class="enhanced">
<slot :enhancedData="processedData"></slot>
</div>
</template>
<script>
export default {
data() {
return {
processedData: transformData(this.originalData)
}
},
props: ['originalData']
}
</script>
<template>
<keep-alive :include="['ComponentA', 'ComponentB']">
<component :is="currentComponent"></component>
</keep-alive>
</template>
<template>
<transition name="fade" mode="out-in">
<keep-alive>
<component :is="currentComponent"></component>
</keep-alive>
</transition>
</template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
export default {
activated() {
console.log('コンポーネントがアクティブになりました')
this.startPolling()
},
deactivated() {
console.log('コンポーネントが非アクティブになりました')
this.stopPolling()
}
}
<!-- CounterComponent.vue -->
<template>
<div>
<p>カウント: {{ count }}</p>
<button @click="count++">増加</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0
}
}
}
</script>
<keep-alive :max="3">
<router-view></router-view>
</keep-alive>
const AsyncComponent = () => ({
component: import('./AsyncComponent.vue'),
loading: LoadingComponent,
error: ErrorComponent,
delay: 200,
timeout: 3000
})
<!-- Toggle.vue -->
<script>
export default {
props: {
initialValue: Boolean
},
data() {
return {
value: this.initialValue
}
},
methods: {
toggle() {
this.value = !this.value
}
},
render() {
return this.$scopedSlots.default({
value: this.value,
toggle: this.toggle
})
}
}
</script>
<!-- Iterator.vue -->
<template>
<div>
<slot
v-for="(item, index) in items"
:item="item"
:index="index"
:last="index === items.length - 1"
></slot>
</div>
</template>
// PluginSystem.vue
<template>
<div>
<slot :plugins="plugins"></slot>
</div>
</template>
<script>
export default {
data() {
return {
plugins: []
}
},
methods: {
register(plugin) {
this.plugins.push(plugin)
}
}
}
</script>
const customCache = new Map()
export default {
name: 'CustomKeepAlive',
abstract: true,
props: {
max: Number
},
created() {
this.cache = new Map()
},
destroyed() {
for (const [key, vnode] of this.cache) {
customCache.set(key, vnode)
}
},
render() {
const slot = this.$slots.default
const vnode = slot[0]
if (vnode && vnode.componentOptions) {
const key = vnode.key ?? vnode.componentOptions.Ctor.cid
if (this.cache.has(key)) {
vnode.componentInstance = this.cache.get(key).componentInstance
} else {
this.cache.set(key, vnode)
if (this.max && this.cache.size > parseInt(this.max)) {
const oldestKey = this.cache.keys().next().value
this.cache.delete(oldestKey)
}
}
vnode.data.keepAlive = true
}
return vnode
}
}
<template>
<keep-alive>
<component :is="loadComponent()"></component>
</keep-alive>
</template>
<script>
export default {
methods: {
loadComponent() {
return () => ({
component: import('./HeavyComponent.vue'),
loading: LoadingComponent
})
}
}
}
</script>
// main.js
import Vue from 'vue'
const app = new Vue({
data: {
currentView: 'Home'
},
methods: {
setView(view) {
this.currentView = view
}
},
render(h) {
return h('keep-alive', [h(this.currentView)])
}
}).$mount('#app')
// 使用例
app.setView('About')
この解答セットは、Vue.jsのスロットと動的コンポーネントに関するあらゆる側面を網羅しています。初級問題で基本を理解し、中級問題で実践的なスキルを習得し、上級問題で高度なパターンをマスターできる構成になっています。各解答には実際のプロジェクトで活用できる実用的なコード例を示しており、Vue.jsのコンポーネントシステムを深く理解するのに役立ちます。