【愚公系列】《循序渐进Vue.js 3.x前端开发实践》041-案例:优化用户列表页面

举报
愚公搬代码 发表于 2025/02/28 23:31:00 2025/02/28
【摘要】 标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主,2024年华为云十佳...
标题 详情
作者简介 愚公搬代码
头衔 华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,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 数组,它模拟了一个用户列表,每个用户有 namesex 两个属性。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,则展示所有用户;如果为 01,则过滤并只显示相应性别的用户。
  • searchData:根据搜索框的输入进行过滤。如果输入为空,则展示所有用户。如果有输入,则只显示姓名中包含搜索关键字的用户。

🦋2.4 Vue.watch 监听器

  • Vue.watch(sexFliter, fliterData):当 sexFliter 改变时,调用 fliterData 函数来更新用户列表。
  • Vue.watch(searchKey, searchData):当 searchKey 改变时,调用 searchData 函数来进行搜索过滤。

🦋2.5 模板部分

在模板中,使用了以下功能:

  • 单选框:允许用户选择性别过滤(全部、男、女),通过 v-modelsexFliter 双向绑定。
  • 搜索框:允许用户输入姓名关键字进行搜索,同样通过 v-modelsearchKey 双向绑定。
  • <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;
}
  • containercontent:定义了外部容器和内容区域的间距。
  • .tab:定义了用户列表表格的容器,使用 position: absolute 将其固定。
  • .item:每个用户信息项的样式,包括边框、宽度和居中对齐。还定义了过渡动画 transition: all 0.8s ease,使得列表项在变化时能够平滑过渡。
  • .list-enter-active.list-leave-active:定义了元素进出时的过渡效果。list-enter-fromlist-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 用于监听响应式数据的变化,并执行特定的函数。这里我们监听了两个数据:sexFlitersearchKey

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 的 refwatch 实现数据响应式和自动更新界面。

该代码展示了 Vue 3 的核心功能,如响应式数据、生命周期钩子、事件监听、表单控制和动画效果,适合用作动态交互页面的基础模板。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。