前端开发经验总结(持续更新...)
一、获取到数据再渲染组件,否则显示正在加载
1、添加一个加载状态:使用一个 ref
来表示是否已加载数据。
const loading = ref(true); // 添加一个加载状态
2、更新加载状态:在数据获取成功后,将 loading
状态修改为 false
。
async function fetchmemberStyleList() {
try {
console.log("获取会员风采列表数据");
const res = await memberStyleApi.getmemberStyleList();
memberStyles.value = res.data;
console.log("memberStyles", memberStyles.value);
loading.value = false; // 数据获取成功,更新加载状态
} catch (error) {
console.log("获取会员风采列表数据失败");
loading.value = false; // 如果获取失败,仍然更新加载状态
}
}
3、在模板中使用条件渲染:通过 v-if
控制组件的渲染。
<div v-if="loading">正在加载...</div>
<a-card class="affiliateCard" title="会员风采" v-if="!loading">
<template #extra>
<a href="#">更多 <RightOutlined /></a>
</template>
<div class="affiliateCard-list">
<a-card hoverable class="affiliateCard-item" v-for="item in memberStyles" :key="item.id" :headStyle="cardHeadStyle">
<template #cover>
<img alt="example" src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png" />
</template>
<a-card-meta :title="item.name" class="ant-card-meta-title">
<template #description>{{ item.introduction }}</template>
</a-card-meta>
</a-card>
</div>
</a-card>
二、一些字符串处理方法
// string String
let str = "Hello world"; // 字符数组
console.log(str.length); // 11, 不是方法,是属性
console.log(str.charAt(1)); // e 获得某个位置的字符
console.log(str[1]); // 等价于 str.charAt(1)
// 字符串方法
console.log(str.toUpperCase()); // HELLO WORLD
console.log(str.toLowerCase()); // hello world
// 查找子串
console.log(str.indexOf("l")); // 2 查找子串的位置,没有返回-1
console.log(str.lastIndexOf("l")); // 9 同上,从右边开始查找 >=0说明有
console.log(str.includes("o w")); // true 是否包含子串
console.log(str.startsWith("Hel")); // true 是否以某个子串开头
console.log(str.endsWith("rld")); // true 是否以某个子串结尾
// 获取子串
console.log(str.substring(4, 7)); // o w 截取子串[start, end-1],子串长度=end-start
console.log(str.substring(4)); // o world 从start截取到末尾
console.log(str.slice(-5)); // world 从后往前截取,负数表示从末尾开始算起
console.log(" str ".trim()); // str,去掉首尾空格"
console.log(str.replace("l", "L")); // HeLLo world
console.log(str.slice(2, 5)); // llo 截取子串,不包含5
三、then 方法(在异步函数成功完成并返回结果后执行)
根据参数获取不同栏目的文章赋值给对应的数组
// ================ 获取文章数据 ======================
async function fetchEssayInfo(type,columnTitle) {
try {
console.log("获取文章数据");
const res = await essayApi.getessayInfo(type,columnTitle);
console.log("获取文章数据成功",res.data);
}
catch (error) {
console.log("获取文章数据失败");
}
}
//学会动态文章列表
const associationDynamicDates = fetchEssayInfo('学会动态');
fetchEssayInfo('学会动态').then(res => {
console.log("学会动态文章列表",res.data);
associationDynamicDates.value = res.data;
});
// 通知公告文章列表
const noticeDates = ref([]);
fetchEssayInfo('通知公告').then(res => {
console.log("通知公告文章列表",res.data);
noticeDates.value = res.data;
});
四、列表分页请求
1、完整代码
<template>
<div class="card-wrapper">
<a-card :headStyle="headStyle">
<template #title>
<span style="margin-right: 8px"><AimOutlined /></span>当前位置:<a href="/">首页 > </a><a href="">{{ props.param }}</a>
</template>
<!-- 列表 -->
<a-list bordered :data-source="Dates" :pagination="pagination" class="card-content">
<template #renderItem="{ item }">
<a-list-item>
<router-link :to="`/viewNews/${item.id}`">
{{ item.textTitle }} <RightOutlined />
</router-link>
<span class="item-date">{{ item.createdTime }}</span>
</a-list-item>
</template>
</a-list>
</a-card>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
import { defineProps } from 'vue';
import { essayApi } from '/@/api/essay';
// 接收父组件传来的 param 和 selectedType
const props = defineProps({
param: {
type: String,
required: true
},
selectedType: {
type: String,
required: true,
}
});
// 使用 param
console.log('右边接收到的参数:', props.param);
console.log("所选文章类型:", props.selectedType);
const emit = defineEmits(['update:modelValue']);
// 卡片样式
const headStyle = {
color: '#108ee9',
fontSize: '13px',
height: '20px',
lineHeight: '20px',
padding: '0 15px',
background: '#f5f7f9',
borderBottom: '1px solid #e8e8e8',
};
// 分页配置
const pageNum = ref(1);
const pageSize = ref(6);
const total = ref(0); // 存储总记录数
// 使用 reactive 来确保 pagination 是响应式的
const pagination = ref({
current: pageNum.value,
pageSize: pageSize.value,
total: total.value,
onChange: (page) => {
pageNum.value = page;
// 更新 pagination.current
pagination.value.current = page;
if (props.selectedType === '全部') {
fetchEssayInfo(pageNum.value, pageSize.value, null, null, props.param, null, );
} else {
fetchEssayInfo(pageNum.value, pageSize.value, null, null, props.param, props.selectedType );
}
},
});
// 文章列表
const Dates = ref([]);
async function fetchEssayInfo( currentPage = 1, currentSize = 6,searchCount = null ,sortItemList = null ,columnTitle, type,) {
try {
console.log("获取文章数据");
const res = await essayApi.getessayInfo(currentPage, currentSize, searchCount, sortItemList, columnTitle, type);
console.log("获取文章列表数据成功", res.data);
Dates.value = res.data.list; // 假设返回的数据格式中包含一个 list 数组
total.value = res.data.total; // 假设返回的数据中包含总记录数
// 更新 pagination.total 和 pagination.current
pagination.value.total = total.value;
pagination.value.current = currentPage;
console.log("获取文章数据成功", Dates.value);
} catch (error) {
console.log("获取文章数据失败");
}
}
// 调用函数以加载不同类型的文章数据
fetchEssayInfo(pageNum.value, pageSize.value, null, null, props.param, null );
// 监听 param 变化
watch(() => props.param, (newVal) => {
console.log("监听到 param 变化", newVal);
if (props.selectedType === '全部') {
fetchEssayInfo(pageNum.value, pageSize.value, null, null, props.param, null );
} else {
fetchEssayInfo(pageNum.value, pageSize.value, null, null, props.param, props.selectedType );
}
});
// 监听父组件传来的 selectedType 变化
watch(() => props.selectedType, (newVal) => {
console.log("监听到 selectedType 变化", newVal);
if (newVal === '全部') {
fetchEssayInfo(pageNum.value, pageSize.value, null, null, props.param, null, );
} else {
fetchEssayInfo(pageNum.value, pageSize.value, null, null, props.param, newVal );
}
});
</script>
<style scoped>
.card-wrapper {
margin: 15px 15px 0 0;
}
.card-content a {
color: #333;
display: block;
width: 500px;
overflow: hidden; /*内容会被修剪,并且其余内容是不可见的。*/
text-overflow: ellipsis; /*显示省略符号来代表被修剪的文本*/
white-space: nowrap; /*文本不会换行,文本会在同一行上继续。*/
}
.card-content a:hover {
color: #1890ff;
text-decoration: underline;
}
.item-date {
color: #999; /* 日期颜色可以自行调整 */
}
</style>
2、代码解释
定义分页相关的响应式数据:
使用
ref
声明了pageNum
(当前页数)、pageSize
(每页记录数)和total
(总记录数),以及一个响应式对象pagination
,用于管理分页相关的状态和行为。
分页配置:
pagination
对象中定义了current
(当前页数)、pageSize
(每页大小)、total
(总记录数)以及onChange
方法。当用户切换页面时,会调用onChange
方法(更新页码并重新调用接口)。
切换页面时的逻辑:
在
onChange
方法中,根据当前页数(page
)更新pageNum
和pagination.current
。它会检查选择的文章类型,如果是“全部”,则会调用fetchEssayInfo
方法获取所有文章;如果是其他类型,则会相应地获取特定类型的文章。
获取文章信息的异步请求:
fetchEssayInfo
方法包含了从后端接口获取文章数据的逻辑。根据传入的当前页数和每页记录数,发送请求并更新文章列表Dates
和总记录数total
。
更新分页信息:
通过接口返回的数据更新
pagination.total
和pagination.current
,确保分页组件能够正确反映当前状态。
对父组件参数变化的监听:
使用
watch
监听props.param
和props.selectedType
的变化,以便在这些值变更时自动重新获取文章数据。
整体而言,通过上述步骤,页面实现了按页加载文章的功能,用户可通过分页组件进行浏览,点击不同的上下页,页面会根据当前页数与选择的类型重新加载文章列表。
前端开发经验总结(持续更新...)
http://localhost:8090//archives/qian-duan-kai-fa-jing-yan-zong-jie-chi-xu-geng-xin...