五、书架开发--2.书架图书列表实现

news2024/7/6 20:54:35

组件涉及+动态组件应用

下面我们先来继续编写书架列表吧即ShelfList.vue书架的数据我们之前就已经获取到了,通过引入mixin即可。

for循环书架数据展示一堆item(图书列表中的方框)

我们要实现图书列表的图书数据显然应该用v-for循环来循环每个方框的图书,书架图书数据之前讲过就是数组中一个个图书状态,可能是一本书可能是一个分类,然后每一个方框即ShelfItem.vue中不是一个图书就是一个分类,所以应该获取数据,然后对这个数据循环给子组件ShelfItem,所以循环中应该把item传给子组件ShelfItem中,所以如下

然后通过component在ShelfItem中实现动态组件

因为每个ShelfItem都有三种状态,而我们根据某些值判断只展示其中的一种状态,所以我们要用动态组件,如下

就是在其中加入<component>标签就代表动态组件,这个组件有三种可能嘛,三个组件中的一个,然后这个动态组件是哪个组件是通过:is="item"来判断它展示哪个组件的,computed计算属性中定义这个item,我们书架数据中type是表示它是哪种状态的,所以我们用this.data.type=1还是=2来判断展示什么,然后是1就展示book,book在data中定义是ShelfItemImage组件,同理如果是=2就展示category...

这种动态组件就是只需要引入不需要components中注册,然后在data中定义属性来分别表示这些组件分别是什么

书架图书列表布局

我们希望这里的方框会随着我们屏幕尺寸变化而变化,我们采用动态羁绊的方式来算出这里每一个方框的高度,因为它的宽度其实是确定的因为我们一排固定排三个方框,所以宽度是固定的,所以我们需要来计算这个高度。这里的一个难点就是来解决计算方框的高度。

首先实现一行三个方框,即做它的宽度

给它flex布局,然后给他flex-flow:row wrap;即让方框们水平布局并且可以换行;然后每个item都flex:0 0 33.33%;即可实现每个框固定一行3个,因为可以换行所以第四个就换行,第二行就又三个这样子,然后给每个方框宽度为整个图书列表宽度的三分之一即width:33.33%。然后item组件那边就给width:100%,height:100%

然后给它高度

如下,我们给方框绑定一个样式即:style,让它高度为itemHeight;然后我们到计算属性computed中定义这个itemHeight,如下

我们给每个方框一些边距,我们用个小技巧:给整个列表左右边距15px然后再给每个方框上下左右各15px边距

然后我们继续做高度

因为屏幕尺寸是会变的嘛,所以我们要先计算出当前屏幕宽度下每个方框的宽度,因为我们获取的数据中每本书的图片宽是250高是350,是有宽高比的,比如此时方框宽度为250时高度应该变成350,这样才能不拉伸坏图书图片。

所以宽:高=5:7,所以5高=7*宽,所以高=7*宽/5

我们先计算当前屏幕尺寸下每个方框的宽度,window.innerWidth/3,但是因为还有边距,所以还要减去边距才是每个方框的正确宽度,最简单的就是直接屏幕宽度减去左右全部边框然后除以3即可得到每个边框的宽度

因为整个列表有左右15px即30px然后每个方框有左/右15px所以每个方框左右边距30*3=90+30=120

但是我们这里不能直接减去120px,我们要先换成rem,我们之前写过一个方法叫realPx,它是将我们的120px转换成rem的自适应的120,所以如下

然后我们就可以把图片放进去展示啦,单书封面+分类书籍封面实现

我们先做单书封面

要获取封面图片,所以shelfitem中的component中要绑定数据data,把其传到那三个组件中

然后我们做分类书籍封面

我们这个分类书籍封面是一个九宫格的布局,当不够9个的时候图片展示在左上进行显示

我们先来看看分类书籍方框中接收的数据是什么样的,因为有两个type=2的所以分类图书组件被动态展示了两次即两个这个分类图书框,所以有两个数据,如下一个是标题为category的分类框的一个是标题为education的分类框的

这个数据我解释一下:书架数据我们获取后是保存在vuex中的ShelfList变量中的,然后我们在列表ShelfList组件中for循环这个ShelfList变量,把里面的每一个item如下分别给一个个ShelfItem中。所以每个ShelfItem中有可能接收到的是一本书也有可能是一个分类书籍;然后我们是在ShelfItem中做判断如果这个ShelfItem中接收的数据是一本书即type=1就展示状态1组件并且把这本书数据传过去,如果这个ShelfItem中接收的数据是一个分类数据即type=2就展示状态2组件并且把这个分类书籍数据传过去;所以状态1组件中接收的数据是一本图书,状态2中接收的数据是一个分类书籍这样子

下面就是vuex中ShelfList保存的数据

这里一个就是一个ShelfItem接收到的,有13个ShelfItem

因为请求回来的书架数据有13个,所以ShelfItem有13个,其中有2个是分类书籍有11个是单书,所以ShelfItem中有2个展示状态2组件,有11个展示状态1组件

回到做分类书籍封面中,清楚了数据是怎样的,我们就来做,分类书籍中图书放在ItemList中,然后我们写布局

九宫格布局,分类书籍中我们是固定只放9本书,所以高不用想书架列表中那样计算,因为九宫格嘛所以肯定就三行所以高度就直接三分之一就好,书架列表你添加的图书多了可能就很多行嘛所以高度就需要计算

有点类似,flex布局让每个图书宽度占三分之一,高度也占三分之一

我们不希望第9本书后显示出来,所以比较简单的做法是直接在最外一层增加一个overflow:hidden;将超出的部分隐藏掉即可

然后增加边距,直接给每本图书上下左右边距即可

但是这样子第一本书距离左侧5px和距离右侧第二本书距离10px不一样,所以改,通过nth-child去分别获取第一个,第二个,第三个元素,第一个元素距离左侧就5px距离右侧就2.5px,中间元素就左右都距离2.5px,最后元素就距离左侧2.5px距离右侧5px这样子

最后做状态3的添加组件封面

状态3表示去到书城首页。因为我们获取回来的书架数据中没有type=3的数据,我们是要手动添加进去,我们在utils下的store.js中添加两个方法,一个方法是往书架数据中添加这个type=3的数据,一个方法是删除书架数据中type=3的数据后面会用

然后我们获取到这个书架数据后先用这个方法把type=3这条数据插入进去,然后再保存到vuex中

然后我们添加样式

接下来做方框点击,先实现点击图书展示详情页以及点击加号转到书城首页

然后我们来实现点击添加+编辑

我们先来实现点击编辑下面方框中都出现一个灰色勾图标,点击方框这个方框的这个勾图标就高亮

方框中添加一个图标,然后v-show编辑模式中才显示

不过我们状态2和状态3时不需要显示

然后点击编辑的时候状态2有一个变暗的显示,我们给它动态组件绑定一个样式,样式条件是在编辑模式下在状态2中才显示这个样式,样式中平时就透明度100%,该绑定样式中透明度就50%

然后编辑状态下,点击方框图书是不能进入详情页才对,所以点击事件中加个判断就好了,不是编辑下才能点击。

然后我们做编辑状态中点击图书展示高亮,我们书架数据中每个数据中都有一个selected属性,这个属性为布尔类型,表示当前是否被选中,默认为false,所以我们利用这个,给勾图标绑定一个样式,如果这个selected为true即被选中时就展示这个样式,样式就给图标改变颜色即可。那什么时候改变这个selected属性呢,你编辑状态下一点击图书就把这个图书的这个属性改为true即可

接下来我们有一个关键动作,我们在vuex中定义一个ShelfSelected变量,用来保存书架图书中选中的图书们。

为什么要增加这个,如果不增加这个变量,我们所有的选中状态就都要到ShelfList中判断,而且ShelfList里面有三种状态,而选中的图书只是在状态1中,统计被选中的图书时就比较麻烦。所以我们定义了一个变量专门用来统计被选中的图书们,放到vuex中

第一步是我们要把选中的图书放到这个shelfSelected中,这个还比较麻烦,我们先实现这一步

如下点击这本书的时候判断这本书是否是选中状态,如果是选中状态就把这本书追加到这个shelfSelected变量中,但是这时候如果是如下用push可能会出现重复的问题

我们在utils下做一个扩展方法,如下给数组的原型中添加一个叫pushWithoutDuplicate的方法,这个方法是用来处理往数组中添加东西的方法。这个atguments是一个类数组对象,它只在函数内部使用,用于存储函数被调用时传递的所有参数。方法中做的就是遍历你传过来的图书,如果这个图书在shelfSelected数组中有过,那就不再添加这本书,如果没有就添加这本书。

然后push改为这个方法

然后取消勾选这本书时,这本书应该从vuex的shelfSelected数组中删除

然后我们编辑中点击这本书,即这本书是被选中就会看那个方法追加到那个shelfSelected变量中,如果我再点击这本书,这本书应该从shelfSelected变量中移除,接下来我们来实现这个移除

所以如果是未被选中状态,我们就把这本书从shelfSelected数组中过滤掉即可,如下改变这个vuex中的变量,改变的值是过滤后的值

这样选中图书保存到vuex的shelfSelected数组就实现了,取消点击时也可以从shelfSelected数组中取消了

我们选中图书的目的是要让它进行一些操作

我们点击编辑后,下方需要出现一些操作栏。当我们一本书都没选的时候操作栏是灰色,选中一本书后它就可以判断这本书的状态,同时还会根据这本书的状态来展示不同的操作栏名称,操作完成后它会有操作完成的提示

先做出菜单栏,并且有点击图书前后的透明度变化

首先我们实现一下操作栏这个tab,给它固定定位,在StoreShelf中引入

然后我们可以看到这个出现的时候,滚动条滚动到最后的时候,这个菜单栏会把最下面那行的书名给遮盖住,这是因为我们滚动条组件不应该按全屏显示,它应该在编辑模式下底部向上有一个这个菜单栏这么高的距离,这样菜单栏才不会遮住这个书名这样子。我们的scroll组件之前有定义这个bottom,所以我们在StoreShelf的scroll组件中直接传入bottom即可

这个bottom平时是0,编辑状态下就变成48,所以我们定义一个变量scrollBottom,然后在watch中去监听编辑状态,如果是编辑状态那么就让scrollBottom变成48,并且调scroll的刷新方法去重新计算滚动条组件的高度

如上,发现并没有成功,这是因为我们切换编辑的时候不应该立即执行refresh(),而是应该等,因为我们编辑的时候会触发一些DOM的操作,比如点击编辑的时候我们会让这个菜单栏这个DOM的显示与否,我们应该在整个DOM对界面变化完成之后再来实现refresh()即等菜单栏渲染出来后再计算滚动条的高度,所以需要调$nextTick,等界面响应变化完了之后我们再来refresh这个scroll

接下来我们做菜单栏的布局,这个tab我们也做过,在computed中建一个tabs方法,方法中返回一个数组,数组中就是这几个tab值,一般有index,然后for循环展示这个数组,然后做一个点击事件点击事件中把数组中这个tab的index传进去,一般就是这样子

每个tab图标不一样,所以在循环里面把四个图标都加进去,根据index来判断当前item的tab显示哪个图标。然后平时图标透明度为50%即灰灰的,然后点击一本图书后就把透明度变成1,所以给这四个图标都绑定一个样式,样式判断就是当前有图书被选中即shelfSelected有值

我们点击编辑然后选中几本图书后又不想选这些书了,然后点击取消后我们再次点击编辑发现刚才选的图书还是选中状态,我们需要的是取消了下次再次点击时这几本书不再是选中状态了,现在做这个

即在点击取消时即非编辑状态时,我们要将vuex中的shelfSelected置回空数组,并且把书架中的每一本书的selected置回原来的false

使用create-api实现tab的弹出框

接下来我们来做点击tab然后出现弹出框,这些弹出框被大量使用,但是每处使用的弹出框中的文字是不一样的,所以怎么实现这个弹出框

这个弹框组件就是我们之前做到 toast.vue,我们的Toast组件,这里也要多次被使用,但是每次其他组件要用它的时候每次都要先引入它然后注册它使用它然后每次还要调用弹框组件中的show方法让这个弹框显示,就比较麻烦

介绍一个重要的方法,叫create-api,这个库可以让我们组件与组件之间实现真正的解构,而我们只要通过javaScript的API就可以实现组件的调用

我们安装这个库

然后到main.js中引入这个库

在cerate-api.js中我们将这个vue-create-api引用进来,然后将vue也引入进来,把我们要用的Toast组件也引入进来

通过Vue.use(CreateAPI)来使用这个插件,use完后我们就会在Vue中挂载一个createAPI方法,通过这个createAPI方法传入Toast,然后就可以通过api的形式调用我们的Toast,我们调用这个cerateAPI方法的时候create-api这个插件就会帮我们在Vue的实例上面扩展出一个前面叫create后面叫我们引入的组件名称Toast即$createToast的方法

具体这么用:

我们直接通过this.$createToast(),然后我们通过里面的¥props属性传入一个对象,这个对象就是我们toast组件需要的参数,然后这个this.$createToast()就是创建了这个弹出框的DOM,然后调用弹出框组件中show方法即可显示出这个弹出框。就不用引入弹出框也不用注册使用,就直接下面这样就可以直接使用这个组件了就比较方便。注意用这个的话toast组件中要加属性name:'toast'

我们可以更加简化,我们在create-api.js中,直接调用mixin,通过全局mixin增加一个方法,方法我们就叫toast,传入一个setting,然后把我们这个this.$createToast({ $props:setting }),这样我们要用这个组件的时候就直接通过this.toast()即可使用这个组件啦,贼啦方便

我们来到元素中看看它,它这个是在最外层给我们创建的toast,不是在我们vue渲染的app中,和我们vue渲染的app那个是不一样的,是添加在我们body后面而不是vue的app中,所以对于这一类添加的样式,我们通常建议比如像弹窗这种全屏的,建议是做全屏的用这个,如果你是想直接嵌在vue里面那就不要用这个

然后我们再建那个白色的弹窗组件,也多处用,所以我们也使用create-api,如下

然后写popup布局,因为各处的按钮数量可能不同,而按钮中有标题属性有的还有danger,所以我们把btn定义为一个数组,然后如下我们给这个弹窗一个固定定位。然后哪里用这个弹窗就哪里调用它

接下来我们增加一些按钮,每个地方按钮文字标题文字是不一样的,是在当前组件中传不同的值过去给弹窗组件的,所以如下,按钮中又有点击事件

然后给背景和弹窗分别添加过渡动画,但是隐藏的时候发现没有过渡动画,这是因为你点击背景隐藏的时候直接popupVisible变为false了,popupVisible控制着整个弹窗,你这个过渡动画就在这个popupVisible里面,popupVisible为false即隐藏了,所以自然过渡动画就显示不了,所以我们再定义一个Visible来控制弹窗的显示隐藏

补充一下:这个阅读器电子书今天又展示不出来,发现是192.168.xx又改了,修改一下环境变量就又好了,每次改环境变量的时候记得重新运行项目,不然不行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1590360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实战解析:SpringBoot AOP与Redis结合实现延时双删功能

目录 一、业务场景 1、此时存在的问题 2、解决方案 3、为何要延时500毫秒&#xff1f; 4、为何要两次删除缓存&#xff1f; 二、代码实践 1、引入Redis和SpringBoot AOP依赖 2、编写自定义aop注解和切面 3、application.yml 4、user.sql脚本 5、UserController 6、U…

计算机网络——TCP和UDP协议

目录 前言 前篇 引言 TCP与UDP之间的区别 TCP 三次握手 为什么要三次握手而不是两次握手&#xff1f; 丢包问题与乱序问题的解决 四次挥手 为什么客户端需要等待超时时间&#xff1f; UDP协议 TCP和UDP的主要区别 前言 本博客是博主用于复习计算机网络的博客&…

【Jenkins】Jenkins自动化工具介绍

目录 技术背景常规的手动打包步骤 Jenkins简介起源与发展Jenkins的核心价值1.自动化1.1代码构建1.2测试自动化1.3自动部署 2.持续集成与持续部署CI/CD的概念如何减少集成问题更快速地发布软件版本 Jenkins优势Jenkins的主要竞争对手Travis CI:CircleCI:GitLab CI: Jenkins与其他…

阿里云9元服务器租用收费价格表_免费云服务器领取

2024年最新阿里云服务器租用费用优惠价格表&#xff0c;轻量2核2G3M带宽轻量服务器一年61元&#xff0c;折合5元1个月&#xff0c;新老用户同享99元一年服务器&#xff0c;2核4G5M服务器ECS优惠价199元一年&#xff0c;2核4G4M轻量服务器165元一年&#xff0c;2核4G服务器30元3…

出海企业如何从海外云手机中受益?

随着全球化的推进&#xff0c;越来越多的企业开始将目光投向海外市场。然而&#xff0c;不同国家和地区的网络环境、政策限制&#xff0c;以及语言文化的差异&#xff0c;给出海企业的市场拓展带来了诸多挑战。在这一背景下&#xff0c;海外云手机作为一种新兴解决方案&#xf…

等保测评2.0——网络安全等级保护测评的初步了解

一、什么是网络安全等级保护测评&#xff1f; 二、网络安全等级保护&#xff0c;保护的是什么&#xff1f; 等级保护对象&#xff1a;网络安全等级保护工作直接作用的对象。&#xff08;注&#xff1a;主要包括信息系统、通信网络设施和数据资源等&#xff09; 计算机信息系统…

设计模式代码实战-抽象工厂模式

1、问题描述 小明家新开了两个工厂用来生产家具&#xff0c;一个生产现代风格的沙发和椅子&#xff0c;一个生产古典风格的沙发和椅子&#xff0c;现在工厂收到了一笔订单&#xff0c;请你帮他设计一个系统&#xff0c;描述订单需要生产家具的信息。 输入试例&#xff1a; 3 …

【设计模式】六大设计原则

设计原则 研究 23 种设计模式是困难的&#xff0c;甚至是没必要的六大设计原则零、单一职责原则开闭原则里氏代换原则依赖倒置原则接口隔离原则迪米特法则合成复用原则 研究 23 种设计模式是困难的&#xff0c;甚至是没必要的 设计模式有23种&#xff0c;我认为对普通人来说想…

【Python】读取时间判定操作次数问题和一些解决办法

几种类 datetime.striptime() 计算两个字符串之间的时间差 datetime.striptime()计算两个字符串之间的时间差 datatime类提供函数处理日期和时间 Striptime()分析字符串值以固定格式表示时间然后存储为函数参数 输出就是&#xff1a; time.sleep() time模块打印时间按照对…

python--递归算法篇

1、给定一个包含n1个整数的数组nums&#xff0c;其数字在1到n之间&#xff08;包含1和n&#xff09;&#xff0c; 可知至少存在一个重复的整数&#xff0c;假设只有一个重复的整数&#xff0c;请找出这个重复的数 def repeat(ls:list) -> list:#把个数超过1的数&#xff0c…

AutoCAD 2024 安装注册教程

前言 大家好&#xff0c;我是梁国庆。 本篇分享的安装包是 AutoCAD 的全新版本——AutoCAD 2024&#xff0c;下文安装教程中简称 AutoCAD。 时间&#xff1a;2024年4月8日。 获取 AutoCAD 安装包 我已将本篇所使用的安装包打包上传至百度云&#xff0c;扫描下方二维码关注…

014:vue3 van-list van-pull-refresh实现上拉加载,下拉刷新

文章目录 1. 实现上拉加载&#xff0c;下拉刷新效果2. van-list&#xff0c;van-pull-refresh组件详解2.1 van-list组件2.2 van-pull-refresh组件 3. 完整案例4. 坑点&#xff1a;加载页面会一直调用加载接口 1. 实现上拉加载&#xff0c;下拉刷新效果 通过下拉刷新加载下一页…

DMA的认识

DMA介绍 Q:什么是DMA&#xff1f; DMA( Direct Memory Access&#xff0c;直接存储器访问 ) 提供在 外设与内存 、 存储器和存储器 、 外设 与外设 之间的 高速数据传输 使用。它允许不同速度的硬件装置来沟通&#xff0c;而不需要依赖于 CPU &#xff0c;在这个时间中&am…

Matlab与ROS(1/2)---Message(三)

0. 简介 消息是ROS中交换数据的主要容器。主题和服务使用消息在节点之间传输数据。为了标识其数据结构&#xff0c;每条消息都有一个消息类型。例如&#xff0c;来自激光扫描仪的传感器数据通常以sensor_msgs/LaserScan类型的消息发送。每种消息类型标识消息中包含的数据元素。…

汽车制造业PMC组态应用最佳实践

01案例及行业介绍 汽车制造工业是我国国民经济的重要支柱产业&#xff0c;汽车制造工厂一般包含冲压、焊装、涂装、总装四大车间。每辆汽车的生产过程被分解成很多加工任务下发给各个车间进行完成。车辆从冲压车间开始到总装车间结束一直进行不同类型的工序加工。 PMC即生产控…

docker 上达梦导入dump文件报错:本地编码:PG GBK,导入女件编码:PGGB18030

解决方案&#xff1a; 第一步进入达梦数据容器内部 docker exec -it fc316f88caff /bin/bash 第二步&#xff1a;在容器中 /opt/dmdbms/bin目录下 执行命令 cd /opt/dmdbms/bin./dimp USERIDSYSDBA/SYSDBA001 FILE/opt/dmdbms/ZFJG_LJ20240407.dmp SCHEMASZFJG_LJUSERIDSYSD…

ChatGPT基础(二) ChatGPT的使用和调优

文章目录 ChatGPT的特性采用关键词进行提问给ChatGPT指定身份提升问答质量的策略1.表述方式上的优化2.用"继续"输出长内容3.营造场景4.由浅入深&#xff0c;提升问题质量5.预设回答框架和风格 ChatGPT的特性 1.能够联系上下文进行回答 ChatGPT回答问题是有上下文的&…

微服务学习 Eureka注册中心

服务调用时候出现问题&#xff0c;当服务者很多时候&#xff0c;比如不同的端口。消费者如何找到服务者的地址&#xff1f;又如何判断服务者是否健康。 Eureka基本原理&#xff1a; 总结:如果有多个服务提供者&#xff0c;消费者该如何选择&#xff1f; 搭建Eureka注册中心: 1.…

django基于python的法院执法案件管理系统

本课题使用Python语言进行开发。代码层面的操作主要在PyCharm中进行&#xff0c;将系统所使用到的表以及数据存储到MySQL数据库中&#xff0c;方便对数据进行操作本课题基于WEB的开发平台&#xff0c;设计的基本思路是&#xff1a; 框架&#xff1a;django/flask 后端&#xff…

【YOLOv9改进[损失函数]】使用MPDIou回归损失函数帮助YOLOv9模型更优秀

本文中&#xff0c;第一部分概述了各种回归损失函数&#xff0c;当然也包括了今天的主角MPDIou。第二部分内容为在YOLOv9中使用MPDIou回归损失函数的方法。 1 回归损失函数&#xff08;Bounding Box Regression Loss&#xff09; 边界框回归损失计算的方法包括GIoU、DIoU、CI…