一:分类页面布局
没有解释的部分都是之前学过的内容,如果看不懂请自行复习哦 ~
页面骨架wxml编写:
wxml分析:整个页面布局分为左右两部分,再配合列表渲染将数据传入组件。
flex-warp是什么?
我们知道,flex-direction的默认取值是row,也就是按行排列。在按行排列的时候,flex布局有一个非常沙雕的特性,它不会换行!!!
也就是不管图片有多少张,它都只有一行,超出一行大小的部分图片就消失了,看不见,不会按我们理想状态想的排到下一行。
我们需要通过flex-wrap(默认值是no-wrap也就是不换行)手动设置值为wrap(换行)。
二:拉取数据
在data.class设置所有分类名,在onLoad中向服务器拉取数据并传递给data.book
数据渲染之后如图所示:
哭了:界面长这样我也觉得不怎么好看,但是我实在是懒得想了,今天单纯想界面布局想了几个小时
三:实现点击选中某个分类
当点击微信屏幕的时候,手机系统将点击的位置的信息传递给了微信,微信再传递给了小程序,小程序中通过bindtap属性用来处理用户点击。
格式:bindtap="方法名"
方法(我命名为select)接受一个参数(我命名为e),用来传递需要传递的信息。需要传递的信息需要在组件的data-xxx属性中设置。
格式:
信息名自取
坑来了:当你设置的信息名有多个单词的时候,这个信息名建议全部字母都写小写,如果你写大写会被系统自动转换成小写。
我给信息名取名叫class,传递是信息的分类名,也就是数据渲染中的item
补充说明:许多程序员在处理点击这些用户操作的时候,心照不宣对参数命名为event,e其实是event的简写。当然,你喜欢的话参数名你随便取。
我用鼠标左键点击玄幻两个字。触发了select方法,控制台打印结果如下:
在e.currentTarget.dataset.class出现了玄幻两个字,也就是说e.currentTarget.dataset.class打印的值是我们在data-class中绑定的。如果我们点击其他分类,同样的也会在控制台输入对应的分类名。
四:实现分类动态样式
要实现样式动图变化,首先你得知道当前选中的样式是什么。
在data中增加一个select变量用来进行存储当前选中的样式,进入页面第一个分类就是玄幻,所以我们给它一个默认值“玄幻”。如果你不给这个默认值,那初始状态就什么分类也没有选中,这和我们的常识不符。
在select方法中通过this.setData更新data中select变量值为当前选中的分类名:
补充:三元运算符
格式:"条件表达式?表达式1:表达式2"
如果条件表达式的值为true,就执行表达式1
如果条件表达式的值为false,就执行表达式2
a=b是把b的值给a,也就是赋值的意思
a==b是判断a和b的值是否相等,相等返回true,不相等返回false
我们对class的值进行数据渲染,当data中的select也就是当前选中的分类名和item也就是当前text组件绑定的分类名相同时表达式输出结果为select字符串,否则输出空字符串。
也就是选中的text组件class属性的值是select,未选中的组件class属性的值是空字符串。
注意:不管是表达式1还是表达式2,字符串都是用的单引号。我们给属性值加上了双引号,如果里面的字符串也是双引号就会报错。
像这种select":""}}"双引号太多了,我们当然知道要怎么划分,但是系统无法判断哪个双引号是结尾的双引号,所以就报错了。
编写选中时组件的样式:
border-radius实际上的设置圆角边框,具体效果参考下图,如果还不能理解可通过设置不同大小的rpx值对比。当width和height相等时,border-radius设置为50%图片就变成了圆形。
随便选两个分类作为示例:
有的人可能不理解我为什么要在.select左边加个#left,毕竟用.select足以选中这个组件了。从最初到现在,我们介绍过很多种选择器了。在实际开发中,经常会出现多个选择器选择同一个组件的情况,那这个时候应该用哪个选择器写的样式呢?
这个时候就涉及到了选择器的优先级
如果你只写.select,优先级小于上面的#left text,也就是说被选中的分类border和border-radius是可以显示的,但是color不显示下面设置的rgb(16,255,255)而是显示上面的#999999
常见选择器优先级:id>class>组件名
而#left text的优先级是id+组件名两个优先级相加,大于.select的单纯class选择器,又小于#left .select的id+class选择器。
出现了一个奇怪的问题hhh:
遇到这种问题,二话不说就去看样式,结果发现是是包裹图片的view没有设置宽高,图片少时就出现了拉伸的情况。
解决框被拉伸,将image和包裹它的view设置为同宽高:
五:实现展示不同分类的数据
总感觉少了点什么,于是加上了一个全部分类。默认选取的类型select也进行了更改。
切换分类时,数据渲染所对应的data中的数组的数据要变成对应分类的书籍信息,所以我在onLoad中增加了selectBook数组作为随时可以更改数据的数组,如下图初始状态book和selectBook的数据是一样的。也就是我们初始选定展示的“全部”。
将wxml中的数据渲染也从book改为selectBook
定义一个叫selectBook的数组型变量用来存放选中的分类的书籍数据。
for循环
固定套路:
for (var i = 0; i < 数组名.length; i++) {
执行代码
}
在js中每一个数组都有一个叫length的属性,这个属性是系统默认给的,属性值是数组的长度,也就是数组里有多少个项。
注意:在某些编程语言中数组的length是方法而不是属性,如果你学习过其他编程语言,注意区分哦~
for(var i=0;i=数组名.length的时候程序就不执行了。
怎么获取数组的某个项?
格式:数组名[数组下标]
数组下标和i一样从零到小于数组名.length,且值是完全相等的,所以我们可以用数组名[i]的形式获取数组的每一项,并将每一项书籍信息中的分类名和选中的分类名对比,分类名相同则通过数组的push方法(数组自带的方法),也就是数组名.push(需要增加的部分)的格式将这项添加进存放选择书籍类型数据的selectBook数组。
具体实现:
在for里面写原来我们学习过的if语句判断分类名是否相同并对数据进行处理。
最后通过this.setData将临时定义的selectBook数组(也就是var selectBook=[]这个叫selectBook的空数组)的值传递给data中的selectBook变量。
小提示:因为我懒得想名字所以在这里出现了很多个selectBook,应该可以分清哪个selectBook是用来干嘛的吧
还有,用this.data获取data中的数据,用this.setData设置data中的数据,不要混淆了哦~
具体代码如下:
吐槽:我在GitHub、csdn或者其他代码平台看一些程序员写的小程序代码时,发现很多人在选中一个分类时直接向后台请求这个分类的数据,这样做确实可以,但是频繁的请求会大量消耗服务器资源,如果你的服务器非常好,无所谓这点资源消耗,那你确实可以这样做,但是我们使用的是云开发服务器,它非常脆弱,所以我用只请求了一次数据,后续分类的切换都是在这个数据基础上进行。
数据不够用了。
而且有的分类没有数据,有的分类只有一本。这里面没什么技术含量,就是写数据很繁琐。
最后再改改看能不能更好看一点hhh