Vue3电商项目实战-首页模块6【22-首页主体-补充-vue动画、23-首页主体-面板骨架效果、4-首页主体-组件数据懒加载、25-首页主体-热门品牌】
文章目录
- 22-首页主体-补充-vue动画
- 23-首页主体-面板骨架效果
- 24-首页主体-组件数据懒加载
- 25-首页主体-热门品牌
22-首页主体-补充-vue动画
目标: 知道vue中如何使用动画,知道Transition组件使用。
当vue中,显示隐藏,创建移除,一个元素或者一个组件的时候,可以通过transition实现动画。

如果元素或组件离开,完成一个淡出效果:
<transition name="fade"><p v-if="show">100</p>
</transition>
.fade-leave {opacity: 1
}
.fade-leave-active {transition: all 1s;
}
.fade-leave-to {opcaity: 0
}
- 进入(显示,创建)
- v-enter 进入前 (vue3.0 v-enter-from)
- v-enter-active 进入中
- v-enter-to 进入后
- 离开(隐藏,移除)
- v-leave 进入前 (vue3.0 v-leave-from)
- v-leave-active 进入中
- v-leave-to 进入后
多个transition使用不同动画,可以添加nam属性,name属性的值替换v即可。
23-首页主体-面板骨架效果
目的: 加上面板的骨架加载效果
定义一个骨架布局组件:
src/views/home/components/home-skeleton.vue
<template><div class='home-skeleton'><div class="item" v-for="i in 4" :key="i" :style="{backgroundColor:bg}"><XtxSkeleton bg="#e4e4e4" width="306px" height="306px" animated /><XtxSkeleton bg="#e4e4e4" width="160px" height="24px" animated /><XtxSkeleton bg="#e4e4e4" width="120px" height="24px" animated /></div></div>
</template><script>
export default {name: 'HomeSkeleton',props: {bg: {type: String,default: '#fff'}}
}
</script><style scoped lang='less'>
.home-skeleton {width: 1240px;height: 406px;display: flex;justify-content: space-between;.item {width: 306px;.xtx-skeleton ~ .xtx-skeleton{display: block;margin: 16px auto 0;}}
}
</style>
在 home-hot home-new 组件分别使用
<HomePanel title="人气推荐" sub-title="人气爆款 不容错过">
+ <div style="position: relative;height: 426px;">
+ <Transition name="fade">
+ <ul v-if="goods.length" ref="pannel" class="goods-list"><li v-for="item in goods" :key="item.id"><RouterLink to="/"><img :src="item.picture" alt=""><p class="name">{{item.title}}</p><p class="desc">{{item.alt}}</p></RouterLink></li></ul>
+ <HomeSkeleton v-else />
+ </Transition>
+ </div></HomePanel>
<template><HomePanel title="新鲜好物" sub-title="新鲜出炉 品质靠谱"><template v-slot:right><XtxMore /></template>
+ <div style="position: relative;height: 406px;">
+ <Transition name="fade">
+ <ul v-if="goods.length" ref="pannel" class="goods-list"><li v-for="item in goods" :key="item.id"><RouterLink to="/"><img :src="item.picture" alt=""><p class="name">{{item.name}}</p><p class="price">¥{{item.price}}</p></RouterLink></li></ul>
+ <HomeSkeleton bg="#f0f9f4" v-else />
+ </Transition>
+ </div></HomePanel>
</template>
在 src/assets/styles/common.less 定义动画
.fade{&-leave {&-active {position: absolute;width: 100%;transition: opacity .5s .2s;z-index: 1;}&-to {opacity: 0;}}
}
注意:
- 动画的父容器需要是定位,防止定位跑偏。
24-首页主体-组件数据懒加载
目的: 实现当组件进入可视区域在加载数据。
我们可以使用 @vueuse/core 中的 useIntersectionObserver 来实现监听进入可视区域行为,但是必须配合vue3.0的组合API的方式才能实现。
大致步骤:
- 理解
useIntersectionObserver的使用,各个参数的含义 - 改造 home-new 组件成为数据懒加载,掌握
useIntersectionObserver函数的用法 - 封装
useLazyData函数,作为数据懒加载公用函数 - 把
home-new和home-hot改造成懒加载方式
落的代码:
1.先分析下这个useIntersectionObserver 函数:
// stop 是停止观察是否进入或移出可视区域的行为
const { stop } = useIntersectionObserver(// target 是观察的目标dom容器,必须是dom容器,而且是vue3.0方式绑定的dom对象target,// isIntersecting 是否进入可视区域,true是进入 false是移出// observerElement 被观察的dom([{ isIntersecting }], observerElement) => {// 在此处可根据isIntersecting来判断,然后做业务},
)
2.开始改造 home-new 组件:src/views/home/components/home-new.vue
- 进入可视区后获取数据
<div ref="box" style="position: relative;height: 406px;">
// 省略。。。
<script>
import HomePanel from './home-panel'
import HomeSkeleton from './home-skeleton'
import { findNew } from '@/api/home'
import { ref } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
export default {name: 'HomeNew',components: { HomePanel, HomeSkeleton },setup () {const goods = ref([])const box = ref(null)const { stop } = useIntersectionObserver(box,([{ isIntersecting }]) => {if (isIntersecting) {stop()findNew().then(data => {goods.value = data.result})}})return { goods, box }}
}
</script>
3.由于首页面板数据加载都需要实现懒数据加载,所以封装一个钩子函数,得到数据。
src/hooks/index.js
// hooks 封装逻辑,提供响应式数据。
import { useIntersectionObserver } from '@vueuse/core'
import { ref } from 'vue'
// 数据懒加载函数
export const useLazyData = (apiFn) => {// 需要// 1. 被观察的对象// 2. 不同的API函数const target = ref(null)const result = ref([])const { stop } = useIntersectionObserver(target,([{ isIntersecting }], observerElement) => {if (isIntersecting) {stop()// 调用API获取数据apiFn().then(data => {result.value = data.result})}})// 返回--->数据(dom,后台数据)return { target, result }
}
4.再次改造 home-new 组件:src/views/home/components/home-new.vue
import { findNew } from '@/api/home'
+import { useLazyData } from '@/hooks'
export default {name: 'HomeNew',components: { HomePanel, HomeSkeleton },setup () {
+ const { target, result } = useLazyData(findNew)
+ return { goods: result, target }}
}
+ <div ref="target" style="position: relative;height: 426px;">
5.然后改造 home-hot 组件:src/views/home/components/home-hot.vue
+ <div ref="target" style="position: relative;height: 426px;">
import { findHot } from '@/api/home'
import HomePanel from './home-panel'
import HomeSkeleton from './home-skeleton'
+import { useLazyData } from '@/hooks'
export default {name: 'HomeHot',components: { HomePanel, HomeSkeleton },setup () {
+ const { target, result } = useLazyData(findHot)
+ return { target, list: result }}
}
25-首页主体-热门品牌
目的: 实现品牌的展示,和切换品牌效果。
基本步骤:
- 准备基础布局组件
- 获取数据实现渲染,完成切换效果
- 加上骨架效果和数据懒加载
落的代码:
.基础结构:src/views/home/components/home-brand.vue`
<template><HomePanel title="热门品牌" sub-title="国际经典 品质保证"><template v-slot:right><a href="javascript:;" class="iconfont icon-angle-left prev"></a><a href="javascript:;" class="iconfont icon-angle-right next"></a></template><div class="box" ref="box"><ul class="list" ><li v-for="i in 10" :key="i"><RouterLink to="/"><img src="http://zhoushugang.gitee.io/erabbit-client-pc-static/uploads/brand_goods_1.jpg" alt=""></RouterLink></li></ul></div></HomePanel>
</template><script>
import HomePanel from './home-panel'
export default {name: 'HomeBrand',components: { HomePanel }
}
</script><style scoped lang='less'>
.home-panel {background:#f5f5f5
}
.iconfont {width: 20px;height: 20px;background: #ccc;color: #fff;display: inline-block;text-align: center;margin-left: 5px;background: @xtxColor;&::before {font-size: 12px;position: relative;top: -2px}&.disabled {background: #ccc;cursor: not-allowed;}
}
.box {display: flex;width: 100%;height: 345px;overflow: hidden;padding-bottom: 40px;.list {width: 200%;display: flex;transition: all 1s;li {margin-right: 10px;width: 240px;&:nth-child(5n) {margin-right: 0;}img {width: 240px;height: 305px;}}}
}
</style>
2.使用组件:src/views/home/index.vue
<!-- 人气推荐 --><HomeHot /><!-- 热门品牌 -->
+ <HomeBrand />
+import HomeBrand from './components/home-brand'
export default {name: 'xtx-home-page',
+ components: { HomeCategory, HomeBanner, HomeNew, HomeHot, HomeBrand }
}
2.获取数据和切换效果:
- 由于最后会使用到数据懒加载,那么我们也会使用组合API实现。
- 业务上,只有两页数据切换,0—>1 或者 1—>0 的方式。
<template><HomePanel title="热门品牌" sub-title="国际经典 品质保证"><template v-slot:right><a @click="toggle(-1)" :class="{disabled:index===0}" href="javascript:;" class="iconfont icon-angle-left prev"></a><a @click="toggle(1)" :class="{disabled:index===1}" href="javascript:;" class="iconfont icon-angle-right next"></a></template><div class="box"><ul v-if="brands.length" class="list" :style="{transform:`translateX(${-index*1240}px)`}"><li v-for="item in brands" :key="item.id"><RouterLink to="/"><img :src="item.picture" alt=""></RouterLink></li></ul></div></HomePanel>
</template><script>
import { ref } from 'vue'
import HomePanel from './home-panel'
import { findBrand } from '@/api/home'
import { useLazyData } from '@/hooks'
export default {name: 'HomeBrand',components: { HomePanel },setup () {// 获取数据const brands = ref([])findBrand(10).then(data => {brands.value = data.result})// 切换效果,前提只有 0 1 两页const index = ref(0)// 1. 点击上一页// 2. 点击下一页const toggle = (step) => {const newIndex = index.value + stepif (newIndex < 0 || newIndex > 1) returnindex.value = newIndex}return { brands, toggle, index }}
}
</script>
3.加上数据懒加载和骨架效果
<template><HomePanel title="热门品牌" sub-title="国际经典 品质保证"><template v-slot:right><a @click="toggle(-1)" :class="{disabled:index===0}" href="javascript:;" class="iconfont icon-angle-left prev"></a><a @click="toggle(1)" :class="{disabled:index===1}" href="javascript:;" class="iconfont icon-angle-right next"></a></template>
+ <div ref="target" class="box">
+ <Transition name="fade">
+ <ul v-if="brands.length" class="list" :style="{transform:`translateX(${-index*1240}px)`}"><li v-for="item in brands" :key="item.id"><RouterLink to="/"><img :src="item.picture" alt=""></RouterLink></li></ul>
+ <div v-else class="skeleton">
+ <XtxSkeleton class="item" v-for="i in 5" :key="i" animated bg="#e4e4e4" width="240px" height="305px"/>
+ </div>
+ </Transition></div></HomePanel>
</template><script>
import { ref } from 'vue'
import HomePanel from './home-panel'
import { findBrand } from '@/api/home'
+import { useLazyData } from '@/hooks'
export default {name: 'HomeBrand',components: { HomePanel },setup () {// 获取数据// const brands = ref([])// findBrand(10).then(data => {// brands.value = data.result// })
+ // 注意:useLazyData需要的是API函数,如果遇到要传参的情况,自己写函数再函数中调用API
+ const { target, result } = useLazyData(() => findBrand(10))// 切换效果,前提只有 0 1 两页const index = ref(0)// 1. 点击上一页// 2. 点击下一页const toggle = (step) => {const newIndex = index.value + stepif (newIndex < 0 || newIndex > 1) returnindex.value = newIndex}
+ return { brands: result, toggle, index, target }}
}
</script>
.skeleton {width: 100%;display: flex;.item {margin-right: 10px;&:nth-child(5n) {margin-right: 0;}}}
总结: 注意下useLazyData传参的情况。
相关文章:
Vue3电商项目实战-首页模块6【22-首页主体-补充-vue动画、23-首页主体-面板骨架效果、4-首页主体-组件数据懒加载、25-首页主体-热门品牌】
文章目录22-首页主体-补充-vue动画23-首页主体-面板骨架效果24-首页主体-组件数据懒加载25-首页主体-热门品牌22-首页主体-补充-vue动画 目标: 知道vue中如何使用动画,知道Transition组件使用。 当vue中,显示隐藏,创建移除&#x…...
linux 使用
一、操作系统命令 1、版本命令:lsb_release -a 2、内核命令:cat /proc/version 二、debian与CentOS区别 debian德班和CentOS是Linux里两个著名的版本。两者的包管理方式不同。 debian安装软件是用apt(apt-get install),而CentOS是用yum de…...
基于遗传算法的微电网调度(风、光、蓄电池、微型燃气轮机)(Matlab代码实现)
💥💥💥💞💞💞欢迎来到本博客❤️❤️❤️💥💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清…...
方向导数与梯度下降
文章目录方向角与方向余弦方向角方向余弦方向导数定义性质梯度下降梯度下降法(Gradient descent)是一个一阶最优化算法,通常也称为最速下降法。 要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(…...
Java岗面试题--Java基础(日积月累,每日三题)
目录面试题一:Java中有哪些容器(集合类)?追问:Java中的容器,线程安全和线程不安全的分别有哪些?面试题二: HashMap 的实现原理/底层数据结构? JDK1.7 和 JDK1.8追问一&am…...
java基础—Volatile关键字详解
java基础—Volatile关键字详解 文章目录java基础—Volatile关键字详解并发编程的三大特性:volatile的作用是什么volatile如何保证有可见性volatile保证可见性在JMM层面原理volatile保证可见性在CPU层面原理可见性问题的例子volatile如何保证有序性单例模式使用volat…...
内存检测工具Sanitizers
Sanitizers介绍 Sanitizers 是谷歌开源的内存检测工具,包括AddressSanitizer、MemorySanitizer、ThreadSanitizer、LeakSanitizer。 Sanitizers是LLVM的一部分。 gcc4.8:支持Address和Thread Sanitizer。 gcc4.9:支持Leak Sanitizer和UBSani…...
Triton : OpenAI 开发的用于Gpu开发语言
Triton : OpenAI 开发的用于Gpu开发语言https://openai.com/blog/triton/1、介绍 https://openai.com/blog/triton/ 2、git地址 https://github.com/openai/triton 3、论文 http://www.eecs.harvard.edu/~htk/publication/2019-mapl-tillet-kung-cox.pdf SIMD : Single Inst…...
Python文件操作-代码案例
文章目录文件打开文件open写文件上下文管理器第三方库简单应用案例使用python生成二维码使用python操作excel程序员鼓励师学生管理系统文件 变量就在内存中,文件在硬盘中. 内存空间更小,访问速度快,成本贵,数据容易丢失,硬盘空间大,访问慢,偏移,持久化存储. \\在才是 \的含义…...
活动目录(Active Directory)管理,AD自动化
每个IT管理员几乎每天都在Active Directory管理中面临许多挑战,尤其是在管理Active Directory用户帐户方面。手动配置用户属性非常耗时、令人厌烦且容易出错,尤其是在大型、复杂的 Windows 网络中。Active Directory管理员和IT经理大多必须执行重复和世俗…...
Allegro如何使用Vertext命令修改丝印线段的形状操作指导
Allegro如何使用Vertext命令修改丝印线段的形状操作指导 在用Allegro画丝印线段的时候,如果画了一段不是自己需要形状的线段,无需删除重画,可以用Vertext命令直接编辑 如下图 修改前 修改后 具体操作如下 选择Edit...
Leetcode力扣秋招刷题路-0030
从0开始的秋招刷题路,记录下所刷每道题的题解,帮助自己回顾总结 30. 串联所有单词的子串 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。…...
基于Prometheus和k8s搭建监控系统
文章目录1、实验环境2、Prometheus介绍?3、Prometheus特点3.1 样本4、Prometheus组件介绍5、Prometheus和zabbix对比分析6、Prometheus的几种部署模式6.1 基本高可用模式6.2 基本高可用远程存储6.3 基本HA 远程存储 联邦集群方案7、Prometheus的四种数据类型7.1 C…...
类和对象(下)
类和对象(下)再谈构造函数构造函数体赋值初始化列表explicit关键字static成员静态成员的特性友元友元函数友元类成员函数做友元内部类匿名对象编译器的一些优化再谈构造函数 构造函数体赋值 在创建对象的时候编译器会调用构造函数给对象中的成员变量一…...
达梦数据库单机部署
一、安装前准备 1. 安装环境 操作系统:redhat7.9 达梦数据库版本:V8 内存:2G CPU:x86_64 2. 新建用户组和用户 groupadd dinstall useradd -g dinstall -m -d /home/dmdba -S /bin/bash dmdba passwd dmdba3. 配置参数 vi /etc/security/limits.conf #在末尾添加以下内…...
从零到一学习Flutter——(二)状态和路由
背景 前文提到了Widget的状态,在Flutter中一切都是Widget,那么由Widget组成的页面,会有很多复杂的父子关系,要想交互友好,则需要这些Widget进行通讯,也就是所谓的状态管理。 同时在了解了布局之后,我们会写出很多的页面,那么在这些页面切换,也是一个很重要的能力。 …...
TC358774XBG/TC358775XBG替代方案|CS5518替代TC358774XBG/TC358775XBG设计DSI转LVSD设计资料
TC358774XBG/TC358775XBG替代方案|CS5518替代TC358774XBG/TC358775XBG设计DSI转LVSD设计资料 TC358774XBG/TC358775XBG 芯片的主要功能是作为 DSI - LVDS 通信协议桥接,主芯片的视频数据可通过 DSI 链路流 出,以驱动兼容 LVDS 的显示板。换句话说&#x…...
Linux---Kernal与Shell讲解
目录 Shell简介 什么是Shell Shell分类 内核Kernal Shell简介 什么是Shell 我们首先需要知道一台完整的计算机是由硬件组成的,而人不可以直接与硬件交互,为了完成交互,进行了以下的操作 将硬件设备交由内核管理,给硬件套个内…...
Thiol-PEG-Acid,HS-PEG-COOH,巯基-聚乙二醇-羧基试剂供应
一:产品描述 1、名称 英文:HS-PEG-COOH,Thiol-PEG-Acid 中文:巯基-聚乙二醇-羧基 2、CAS编号:N/A 3、所属分类:Carboxylic acid PEG Thiol PEG 4、分子量:可定制,Thiol-聚乙二…...
数据结构与算法基础-学习-09-线性表之栈的理解、初始化顺序栈、判断顺序栈空、获取顺序栈长度的实现
一、个人理解栈是线性表的一种衍生,和之前的顺序表和链表在插入和删除元素上有较大差异,其他基本相同,栈是数据只能插入表的尾部(栈顶),删除数据时只能删除表的尾部(栈顶)数据&#…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
