【愚公系列】《循序渐进Vue.js 3.x前端开发实践》041-案例:优化用户列表页面
标题 | 详情 |
---|---|
作者简介 | 愚公搬代码 |
头衔 | 华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。 |
近期荣誉 | 2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主,2024年华为云十佳博主等。 |
博客内容 | .NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。 |
欢迎 | 👍点赞、✍评论、⭐收藏 |
🚀前言
在现代 web 应用中,用户列表页面是最常见的界面之一,承载着用户信息的展示、管理和交互。一个设计良好且高效的用户列表页面不仅能提升用户体验,还能有效提高工作效率。然而,随着数据量的增加和功能的复杂化,用户列表页面往往面临着加载速度慢、交互不流畅以及信息展示不清晰等问题。
本篇文章将通过一个实际案例,深入探讨如何优化用户列表页面。我们将分析现有页面的问题,讨论优化的目标,并介绍一系列实用的优化技术和策略,包括数据懒加载、虚拟滚动、分页、搜索和筛选功能的实现,以及界面设计的改进。
🚀一、案例:优化用户列表页面
🔎1. HTML 和基本结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户列表</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<style>
/* 样式定义略,稍后讲解 */
</style>
</head>
<body>
<div id="Application"></div> <!-- Vue 挂载的容器 -->
<script>
// Vue 应用逻辑
</script>
</body>
</html>
- HTML 基本结构:这是一个标准的 HTML 页面结构,其中通过
script
标签引入了 Vue 3 的 CDN 链接。页面的主体部分只有一个<div id="Application"></div>
,它是 Vue 应用挂载的容器。
🔎2. Vue 3 应用的逻辑部分
let mock = [
{ name: "小王", sex: 0 },
{ name: "小红", sex: 1 },
{ name: "小李", sex: 1 },
{ name: "小张", sex: 0 }
];
- 模拟数据:这段代码定义了一个
mock
数组,它模拟了一个用户列表,每个用户有name
和sex
两个属性。sex
的值为0
代表男,1
代表女。
const App = Vue.createApp({
setup() {
// 定义响应式数据
const showDatas = Vue.ref([]); // 存储显示的用户数据
const queryAllData = () => {
// 模拟请求过程,3秒后加载数据
setTimeout(() => {
showDatas.value = mock;
}, 3000);
};
Vue.onMounted(queryAllData); // 组件挂载后调用请求数据的函数
let sexFliter = Vue.ref(-1); // 性别过滤器
let searchKey = Vue.ref(""); // 搜索关键字
// 过滤数据:根据性别过滤
let fliterData = () => {
searchKey.value = ""; // 每次性别变化时清空搜索框
if (sexFliter.value == -1) {
showDatas.value = mock; // 显示所有数据
} else {
showDatas.value = mock.filter((data) => data.sex == sexFliter.value);
}
};
// 搜索数据:根据搜索框输入过滤
let searchData = () => {
sexFliter.value = -1; // 搜索时重置性别过滤
if (searchKey.value.length == 0) {
showDatas.value = mock; // 搜索框为空时显示所有数据
} else {
showDatas.value = mock.filter((data) => data.name.search(searchKey.value) != -1);
}
};
// 监听性别和搜索框的变化
Vue.watch(sexFliter, fliterData);
Vue.watch(searchKey, searchData);
// 返回需要在模板中使用的数据和方法
return { showDatas, searchKey, sexFliter };
},
template: `
<div class="container">
<div class="content">
<input type="radio" :value="-1" v-model="sexFliter"/>全部
<input type="radio" :value="0" v-model="sexFliter"/>男
<input type="radio" :value="1" v-model="sexFliter"/>女
</div>
<div class="content">搜索:<input type="text" v-model="searchKey" /></div>
<div class="content">
<div class="tab">
<div>
<div class="item">姓名</div>
<div class="item">性别</div>
</div>
<transition-group name="list">
<div v-for="(data, index) in showDatas" :key="data.name">
<div class="item">{{ data.name }}</div>
<div class="item">{{ data.sex == 0 ? '男' : '女' }}</div>
</div>
</transition-group>
</div>
</div>
</div>
`
});
App.mount("#Application");
🦋2.1 响应式数据和逻辑
showDatas
:是一个响应式数据,用于存储并展示过滤后的用户列表。sexFliter
:也是响应式的,表示当前选择的性别过滤器,默认值为-1
(表示不进行性别过滤)。0
代表男,1
代表女。searchKey
:用于存储搜索框的输入值,默认值为空字符串。
🦋2.2 数据请求和初始化
queryAllData
:模拟了一个数据请求函数,通过setTimeout
延迟 3 秒后,将mock
数据赋值给showDatas
,模拟异步请求。Vue.onMounted(queryAllData)
:在组件挂载时(即页面加载完成后),会调用queryAllData
方法,加载并展示数据。
🦋2.3 过滤和搜索功能
fliterData
:根据性别过滤用户列表。如果sexFliter
为-1
,则展示所有用户;如果为0
或1
,则过滤并只显示相应性别的用户。searchData
:根据搜索框的输入进行过滤。如果输入为空,则展示所有用户。如果有输入,则只显示姓名中包含搜索关键字的用户。
🦋2.4 Vue.watch
监听器
Vue.watch(sexFliter, fliterData)
:当sexFliter
改变时,调用fliterData
函数来更新用户列表。Vue.watch(searchKey, searchData)
:当searchKey
改变时,调用searchData
函数来进行搜索过滤。
🦋2.5 模板部分
在模板中,使用了以下功能:
- 单选框:允许用户选择性别过滤(全部、男、女),通过
v-model
与sexFliter
双向绑定。 - 搜索框:允许用户输入姓名关键字进行搜索,同样通过
v-model
与searchKey
双向绑定。 <transition-group>
:包裹用户列表,允许对列表项应用过渡动画。当列表项添加、删除或重新排序时,能平滑地过渡。v-for
:通过v-for
渲染用户列表。每个用户项包含两个<div>
,分别展示用户的姓名和性别。
🔎3. CSS 样式
.container {
margin: 50px;
}
.content {
margin: 20px;
}
.tab {
width: 300px;
position: absolute;
}
.item {
border: gray 1px solid;
width: 148px;
text-align: center;
transition: all 0.8s ease;
display: inline-block;
}
.list-enter-active {
transition: all 1s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
}
.list-move {
transition: transform 1s ease;
}
.list-leave-active {
position: absolute;
transition: all 1s ease;
}
container
和content
:定义了外部容器和内容区域的间距。.tab
:定义了用户列表表格的容器,使用position: absolute
将其固定。.item
:每个用户信息项的样式,包括边框、宽度和居中对齐。还定义了过渡动画transition: all 0.8s ease
,使得列表项在变化时能够平滑过渡。.list-enter-active
和.list-leave-active
:定义了元素进出时的过渡效果。list-enter-from
和list-leave-to
设置了初始和结束状态的透明度为 0,实现淡入淡出效果。.list-move
:定义了元素移动时的动画,过渡transform
属性。
🔎4. 详细分析 Vue 功能和生命周期
🦋4.1 响应式数据 (Vue.ref
)
在 Vue 3 中,响应式数据通常是通过 Vue.ref
创建的。通过 ref
,我们可以将数据转换为响应式的,能够在数据发生变化时自动更新界面。
const showDatas = Vue.ref([]); // 用户数据的响应式引用
const sexFliter = Vue.ref(-1); // 性别过滤器的响应式引用
const searchKey = Vue.ref(""); // 搜索框内容的响应式引用
showDatas
用于存储当前用户列表的数据,并在过滤或搜索时更新该值。sexFliter
控制性别过滤器的选择,默认值-1
表示没有过滤。searchKey
存储用户在搜索框中输入的关键字。
🦋4.2 生命周期钩子 (onMounted
)
在 Vue 3 中,生命周期钩子由 Vue
的 API 来管理。例如,onMounted
钩子会在组件挂载完成后自动执行。
Vue.onMounted(queryAllData);
在此例中,当组件挂载到页面后,queryAllData
方法将被调用,模拟加载数据,3秒后将 mock
数据赋值给 showDatas
,并触发视图更新。
🦋4.3 watch
侦听器
Vue.watch
用于监听响应式数据的变化,并执行特定的函数。这里我们监听了两个数据:sexFliter
和 searchKey
。
Vue.watch(sexFliter, fliterData); // 监听性别过滤器变化
Vue.watch(searchKey, searchData); // 监听搜索框输入变化
sexFliter
的变化:当性别过滤器发生变化时,会调用fliterData
函数来过滤数据。searchKey
的变化:当搜索框内容发生变化时,会调用searchData
函数来根据搜索关键字过滤数据。
这种方式确保了每次用户改变性别或搜索关键字时,数据都能实时更新。
🦋4.4 双向绑定 (v-model
)
在模板中,v-model
被用于表单元素(如输入框和单选按钮),它可以实现数据的双向绑定。当用户更改表单元素的值时,Vue 会自动更新对应的响应式数据。
<input type="radio" :value="-1" v-model="sexFliter"/>全部
<input type="radio" :value="0" v-model="sexFliter"/>男
<input type="radio" :value="1" v-model="sexFliter"/>女
- 这里的单选框通过
v-model="sexFliter"
实现了与sexFliter
变量的双向绑定。用户选择性别时,sexFliter
会自动更新为所选的值。
<input type="text" v-model="searchKey" />
- 搜索框通过
v-model="searchKey"
实现了与searchKey
的双向绑定。用户输入时,searchKey
会实时更新,触发watch
中对searchKey
的监听。
🦋4.5 v-for
渲染
v-for
用于遍历 showDatas
数据并渲染每个用户的姓名和性别。
<div v-for="(data, index) in showDatas" :key="data.name">
<div class="item">{{ data.name }}</div>
<div class="item">{{ data.sex == 0 ? '男' : '女' }}</div>
</div>
v-for="(data, index) in showDatas"
遍历showDatas
数组,data
是当前项,index
是索引。- 使用
:key="data.name"
确保每个列表项都有一个唯一的标识,帮助 Vue 高效地进行 DOM 更新。
🦋4.6 transition-group
动画
transition-group
是 Vue 提供的一个标签,用于处理动态列表的过渡动画。
<transition-group name="list">
<div v-for="(data, index) in showDatas" :key="data.name">
<div class="item">{{ data.name }}</div>
<div class="item">{{ data.sex == 0 ? '男' : '女' }}</div>
</div>
</transition-group>
- 在这里,我们使用了
transition-group
来包裹列表项,从而为每个列表项添加过渡动画。 name="list"
指定了过渡的名称,这会影响 CSS 动画的类名(如.list-enter-active
、.list-leave-active
等)。- 这样,当数据变化时(如增、删或排序),Vue 会应用过渡效果,使得元素的插入、删除或移动都变得平滑。
🦋4.7 CSS 动画
.list-enter-active, .list-leave-active {
transition: all 1s ease;
}
.list-enter-from, .list-leave-to {
opacity: 0;
}
.list-move {
transition: transform 1s ease;
}
.list-enter-active
和.list-leave-active
:定义了元素进入和离开时的过渡效果,持续时间为 1 秒,使用ease
缓动函数。.list-enter-from
和.list-leave-to
:定义了进入和离开时的初始和结束状态,透明度为 0,使得元素逐渐显现或消失。.list-move
:定义了列表项移动时的过渡效果,transform
属性的过渡效果可以让元素平滑移动。
🔎5. 总结
这段代码通过 Vue 3 实现了一个动态的用户列表,其中包含了以下功能:
- 用户数据的展示:通过
v-for
渲染每个用户的姓名和性别。 - 过滤功能:允许用户根据性别过滤用户列表。
- 搜索功能:允许用户根据姓名搜索用户。
- 过渡动画:通过
transition-group
和 CSS 动画,为列表项的增删改提供平滑的过渡效果。 - 响应式和生命周期管理:通过 Vue 3 的
ref
和watch
实现数据响应式和自动更新界面。
该代码展示了 Vue 3 的核心功能,如响应式数据、生命周期钩子、事件监听、表单控制和动画效果,适合用作动态交互页面的基础模板。
- 点赞
- 收藏
- 关注作者
评论(0)