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-线性表之栈的理解、初始化顺序栈、判断顺序栈空、获取顺序栈长度的实现
一、个人理解栈是线性表的一种衍生,和之前的顺序表和链表在插入和删除元素上有较大差异,其他基本相同,栈是数据只能插入表的尾部(栈顶),删除数据时只能删除表的尾部(栈顶)数据&#…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...