前端面试七之列表渲染和组件重用
一、列表渲染
<template><div><h1>用户列表</h1><div v-if="loading">加载中...</div><div v-else-if="error" class="error">加载失败:{{ error.message }}</div><ul v-else><li v-for="user in users" :key="user.id"><strong>{{ user.name }}</strong> - {{ user.email }}</li></ul></div>
</template><script>
import axios from 'axios';export default {data() {return {users: [], // 用于存储用户数据loading: true, // 加载状态error: null, // 错误信息};},methods: {// 将接口请求逻辑分离成一个独立方法async fetchUsers() {try {const response = await axios.get('https://jsonplaceholder.typicode.com/users');this.users = response.data; // 将获取到的用户数据存储到 users 中} catch (error) {this.error = error; // 存储错误信息} finally {this.loading = false; // 加载完成}},},mounted() {// 在 mounted 钩子中调用 fetchUsers 方法this.fetchUsers();},
};
</script><style>
.error {color: red;
}
</style>
代码解释
代码解释
(1)分离接口请求逻辑
-
将接口请求逻辑封装到
fetchUsers
方法中,使代码更加模块化。 -
在
fetchUsers
方法中使用async/await
处理异步请求。 -
请求成功时,将响应数据存储到
users
中。 -
请求失败时,将错误信息存储到
error
中。 -
在
finally
块中,将loading
设置为false
,表示加载完成。
(2)在 mounted
钩子中调用方法
-
在
mounted
钩子中调用fetchUsers
方法,确保在组件挂载完成后发起请求。 -
这种方式使代码更加清晰,逻辑更加分离。
(3)v-for
和 v-if
-
v-for
:用于循环渲染列表。v-for="user in users"
表示对users
数组中的每个元素进行循环,并将每个元素赋值给user
。 -
v-if
:用于根据条件显示或隐藏元素。v-if="loading"
表示如果loading
为true
,则显示加载提示;v-else-if="error"
表示如果存在错误,则显示错误信息。
二、组件重用
组件重用是 Vue.js 的一个重要特性,允许你创建可复用的组件,从而提高代码的可维护性和可读性。通过将通用的功能封装成独立的组件,你可以在多个地方重复使用这些组件,并且可以通过传入不同的属性(props)和插槽(slots)来定制它们的行为和外观。
示例:创建一个可重用的自定义按钮组件
1. 创建自定义按钮组件
在 src/components
文件夹中创建一个名为 CustomButton.vue
的文件。
<template><button:style="buttonStyle"><slot>默认按钮文本</slot></button>
</template><script>
export default {name: 'CustomButton',props: {// 按钮的颜色color: {type: String,default: 'blue',},// 按钮的大小size: {type: String,default: 'medium',},},computed: {// 动态生成按钮的样式buttonStyle() {const baseStyle = {backgroundColor: this.color,color: this.textColor,border: 'none',borderRadius: '4px',cursor: 'pointer',transition: 'background-color 0.3s',padding: this.padding,fontSize: this.fontSize,};return baseStyle;},// 根据背景颜色动态调整文字颜色textColor() {return this.color === 'white' ? 'black' : 'white';},// 动态调整按钮的内边距padding() {switch (this.size) {case 'small':return '4px 8px';case 'medium':return '8px 16px';case 'large':return '12px 24px';default:return '8px 16px';}},// 动态调整按钮的字体大小fontSize() {switch (this.size) {case 'small':return '12px';case 'medium':return '14px';case 'large':return '16px';default:return '14px';}},},
};
</script><style scoped>
button {border: none;border-radius: 4px;padding: 8px 16px; /* 默认值 */cursor: pointer;transition: background-color 0.3s;font-size: 14px; /* 默认值 */
}button:hover {opacity: 0.8;
}
</style>
2. 在父组件中使用自定义按钮
在 src/App.vue
文件中引入并使用 CustomButton
组件。
<template><div id="app"><h1>自定义按钮示例</h1><CustomButton color="green" size="large">点击我</CustomButton><CustomButton color="red" size="small">删除</CustomButton><CustomButton color="blue" size="medium">提交</CustomButton><CustomButton color="white" size="medium">白色按钮</CustomButton></div>
</template><script>
import CustomButton from './components/CustomButton.vue';export default {name: 'App',components: {CustomButton,},
};
</script><style>
#app {text-align: center;margin-top: 60px;
}
</style>
(2)父组件
-
1)
CustomButton
组件 -
插槽(Slot):使用
<slot>
元素允许父组件传入按钮的文本内容。如果父组件没有传入内容,则显示默认的“默认按钮文本”。 -
属性(Props):
-
color
:按钮的背景颜色,默认值为'blue'
。 -
size
:按钮的大小,默认值为'medium'
。
-
-
在父组件中,通过
color
和size
属性传入按钮的颜色和大小。 -
使用插槽传入按钮的文本内容。
-
计算属性(Computed Properties):
-
buttonClass
:根据size
动态生成按钮的类名。 -
buttonStyle
:根据color
动态生成按钮的样式。 -
textColor
:根据背景颜色动态调整文字颜色,确保文字在不同背景颜色下都能清晰可见。
-
-
样式(Style):为按钮定义了基本样式,并根据大小动态调整字体大小和内边距。
-