一、列表渲染
<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):为按钮定义了基本样式,并根据大小动态调整字体大小和内边距。