面试题答案
一键面试设计思路
- 基础结构:创建一个列表展示组件,使用
ul
或ol
标签作为列表容器。 - 插槽:利用插槽来处理不同结构的列表项内容。对于默认插槽,放置通用的列表项内容。
- 作用域插槽:如果列表项需要动态数据,使用作用域插槽将数据从子组件传递到父组件,以便父组件能根据这些数据定制列表项的展示。
代码实现
子组件(列表展示组件,假设使用Vue框架)
<template>
<ul>
<li v-for="(item, index) in listData" :key="index">
<slot v-if="!hasScopedSlots" :item="item">
{{ item.text }}
</slot>
<template v-if="hasScopedSlots" v-slot:default="scope">
<!-- 这里scope包含了item数据,父组件可自定义展示 -->
{{ scope.item.text }}
</template>
</li>
</ul>
</template>
<script>
export default {
name: 'ListComponent',
props: {
listData: {
type: Array,
default: () => []
}
},
computed: {
hasScopedSlots() {
return this.$scopedSlots.default
}
}
}
</script>
<style scoped>
ul {
list-style-type: none;
padding: 0;
}
li {
margin: 5px 0;
}
</style>
父组件使用
<template>
<div>
<h2>普通文本列表</h2>
<ListComponent :listData="simpleList">
<template v-slot:default="scope">
{{ scope.item.text }}
</template>
</ListComponent>
<h2>带图标文本列表</h2>
<ListComponent :listData="iconList">
<template v-slot:default="scope">
<i class="icon icon-{{ scope.item.icon }}"></i> {{ scope.item.text }}
</template>
</ListComponent>
</div>
</template>
<script>
import ListComponent from './ListComponent.vue'
export default {
name: 'ParentComponent',
components: {
ListComponent
},
data() {
return {
simpleList: [
{ text: '列表项1' },
{ text: '列表项2' }
],
iconList: [
{ text: '带图标项1', icon: 'home' },
{ text: '带图标项2', icon: 'user' }
]
}
}
}
</script>
<style scoped>
/* 假设这里有图标样式 */
.icon {
margin-right: 5px;
}
.icon-home:before {
content: '🏠';
}
.icon-user:before {
content: '👤';
}
</style>
上述代码以Vue框架为例,展示了如何使用插槽和作用域插槽来创建一个灵活复用的列表展示组件,并在父组件中不同方式使用该组件。如果是其他框架,思路类似,但语法会有所不同。