spu-scroll自定义组件2:
修复高度问题:
在上一次小程序高级电商前端第2周深入理解REST API开发规范 开启三端分离编程之旅<二>----scroll-view组件的灵活应用、async和await问题探讨、spu-scroll自定义组件篇末留下了一个bug,就是底部会空出一大截出来,回忆一下上次咱们所实现的效果:
接下来则先来解决这个bug。
原因分析:
这个原因貌似不太好找,但是呢可以猜测一下,有时候在你找不到精确原因时,就可以大胆的去猜测试错一下,有木有发现这个底部空出来的空间有点像是在上一次我们没有给scroll-view这个控件开启flex布局时界面的元素的高度差不多,回忆一下:
如果去掉它,当时的样子就成这样了:
那有木有可能是scroll-view这个微信官方的控件本身的特性造成的呢?为了验证这点,这里将scroll-view换成普通的view试一下:
此时运行看一下:
此时底部空白的问题就木有了,而且高度刚好是跟元素的高度一样的,非常完美,但是很明显我们不能这样弄,因为如果用view则无法横向滑动了,通过这个小实验能够说明确实跟scroll-view这个控件的特性有关,那么该如何解决呢,这才是重点,有几个思路,其中肯定有个最优解,下面来尝试一下。
解决方法一:设置固定高度
其实最简单能想到的当然就是给scroll-view设置一下固定的高度,肯定木有这个问题,比如:
很明显这种办法比较麻烦,你还得根据内容的高度动态进行计算,所以不可能采用这种方法,最好是其高度由元素自身高度来决定,所以看方法二。
解决方法二:
既然之前我们试过改成view的高度就木问题了,那么,可以试着这样改一下:
此时界面肯定又乱了:
失去flex水平布局了,因为我们木有在view上开启flex布局嘛,所以:
此时布局对了,可高度还是不对,其实吧,这是因为它影响了:
所以去掉:
最后效果如下:
小结:
通过解决这么一个小bug,其实有一个非常重要的原则需要知道:
尽量不要写死宽高!!!
其实对于spu-scroll这个组件在样式的编写中,除了标题的宽度写死了:
都是遵照这一原则来进行编写的,这里举一个为啥不要定死宽度的例子,比如对于container这个样式目前可以看到宽度是木有定义的:
因为本身就是充满整个屏幕的,那如果我们主动定义一个100%的宽度你看会发生啥情况?
此时运行看一下:
不知有木有看出问题?其实有个水平的滚动条出来了。。也就是有种左右晃动的感觉,这是因为宽度算上了左右padding:
比如屏幕宽度是750rpx,你以为的width为100%就只有750rpx对吧,其实不是的,如果有padding的话,整个width是750rpx+padding的左右内边距,所以很显然超出屏幕宽度了,当然就会有水平的滚动条喽,那有木有办法解决呢?其实是有的,在未来这种技巧也会经常用到,那就是更改盒模型,如下:
也就是更改了盒模型之后,整个的宽度就不会算上左右的内边距了。
文字样式调整:
接下来则需要对整个样式再细调一下,首先就是商品名称,目前由于有些显示两行,有些显示一行,所以整体看起来比较乱:
所以先来增加样式:
给文件增加单行限制:
接下来需要对商品名称做一个单行显示,如果超过指定字符则需要后面显示"...",这个如果在Android中很容易,在TextView控件中增加相应的属性既可,但是如果在小程序中就麻烦一些,需要手动来处理,这里有三种实现的思路:
1、在js中对所有的title进行一个过滤,超过指定长度则截取,最后再绑定到页面上;但是这个有点麻烦,得先对源数据进行预处理,然后再绑定。
2、使用css来解决,这个方案这里暂不采用,网上有很多相关资料。【因为它不满足咱们的要求】
3、使用wxs来解决,这也是此次所采用的,因为正好可以借此机会来了解wxs。
WXS与小程序的内核简介:
1、了解WXS:
先来上官网了解一下它:
其中划重点:
我们知道在html中要使用js需要使用<script></script>标签来包裹对吧,而如果在wxml中要想使用js就需要使用wxs来包裹了,如下:
2、WXS跟Javascript的区别:
那wxs跟javascript很类似,那有木有不同呢,有的,对于WXS而言它只能支持ES5的语法【不支持ES6和ES7,所以不能使用像const、``模板字符串、export等非ES5的语法】,而对于我们的js是可以支持到ES7的,所以这个需要注意。
3、为啥不把此逻辑直接写在js当中,而建议在WXS中来写?
在上面三个思路中就提到可以先将源数据的标题先做截断处理,然后再绑定数据进行渲染对吧,但是很明显这个页面上标题的长度截取其实只是跟视图显示层相关,如果把这种字符串截取的处理都放在js中,那么它会污染js中的代码,其实这个也比较好理解,像在Android中对于超长文本的显示其实就是在View中进行显示控制,而不会提前将数据源就做好字长的处理再绑定到View中,所以这块细节需要知道,至于哪些代码应该写在WXS中,随着之后大量练习会慢慢感受到的,先要明白这块的概念。
2、小程序内核简介:
那为啥微信要搞出两套Javascript代码呢【因为WXS也类似于Javascript对吧】? 其实官网这句已经道出其因了:
也就是在程序中,JS是在逻辑层,WXS是在视图层,两者是完全不同的环境。
最后再来了解一下小程序它的运行原理:
总的来说小程序有三套运行环境:Android、IOS、开发工具(PC),而小程序其实是一个Web技术来驱动的,而要想运行小程序需要有一个Web的宿主环境,当然不同的系统上其宿主环境也不一样,每一个宿主环境当然又分为JS逻辑层和WXS视图层,所以针对不同的平台它们的宿主分别为:
- IOS:逻辑层是JavascriptCore,而视图层是WKWebView;
- Android:逻辑层是V8引擎,而视图层是XWeb,它是微信基于chrome内核来做的一个渲染引擎;
- 开发工具(PC):逻辑层是Nw.js,而视图层是Chromium;注意:这开发工具就是指的微信开发者工具哦。
探究使用Css实现的弊端:
在上面的思路2中我们提到过可以使用Css的方式来达到单行文本超出显示...的方案对吧,貌似这种也挺简单的呀,干嘛一定得要用WXS这种新型的技术呢?好,接下来看一下Css的方案,其实很简单,加这么一个样式:
此时你会发现,单行效果有了,文字超长时木有...:
这是因为要想使用css的这种方式,必须得固定宽度才可以,目前咱们这个文本是木有设置宽度的,所以咱们设置试一下:
但是!!!固定宽度有这么一个问题,看这:
其实原因也很简单,是因为文本内容不居中,这里用微信开发者的调试工具看一下就知道了:
那你把内容再设置css让其居中不就行了:
嗯,这样也可以:
但是!!!这种方式定死了宽度总的来说还是不太好,所以说下面还是要用WXS的方式来实现,所以这里将css的这块代码先给注释掉
WXS与Lin UI Filter的应用:
1、导入Lin UI Filter:
那接下来咱们就用WXS的方式来对商品名称的文本进行一个截取,由于我们已经使用了lin-ui, 对于字符串截取的这种通用功能都已经集成了,我们可以在这可以找到:
看它就是以wxs结尾,具体怎么编写wxs在之后我们会有场景使用到的,这里先不用过多考虑细节,那如何为我们所用呢,需要导入一下,如下:
其中一定要注意这个wxs文件路径需要用到相对路径。
2、开始截取:
此时运行:
那偷窥一下这个wxs的实现:
其实就是一段js函数,当然这函数不是咱们自己来编写的,而是使用lin-ui为咱们所封装的对吧,但是未来咱们会大量使用到自己编写的wxs,所以这个知识需要掌握,另外可能觉得在页面标签元素里写了这么一个比较长的表达式感觉不太好,还是将其抽离到js中较妥,这是因为目前的逻辑结构还不够复杂,这块在之后再来慢慢体会使用了wxs它的好吧。
webstorm的骚操作自定义代码片段:
接下来在继续往下学习之前,先来对webstorm这个开发工具来自定义一些开发中常见的快捷方式,这可以大大提高咱们的编写效率,这里就以其中两个在编写css中常见的代码为例来定义快捷键。
1、fr:flex布局水平居中
也就是对应于css的这两段代码:
开始定义一下:
1、创建组:
点击确定:
2、添加具体的模板:
点击确定,咱们来试一下效果:
2、fc:flex布局垂直居中
同样的,咱们快速定义一下:
也来试一下:
小结:
其实这是一种全家桶开发工具通用的定义方式,适用场景就是当你觉得手敲一个代码很麻烦,而且它又是高频使用的,就可以使用此功能。
自定义组件的边距问题与外部样式类应用:
接下来还剩最后一个细节,就是缺少一个外边距:
所以接下来处理一下,这里为了说明自定义组件的外部样式类的问题,会用多种方式来实现。
方法一:
最简单的办法,给这个view加下边距既可:
也就是:
修改一下该css样式:
此时运行貌似看不到效果,原因是咱们的spu-scroll组件的背景色木有设置白色,所以这里补一下:
方法二:引出自定义组件的外部样式类
接下来用另一种方式来实现,这里主要是为了引出如何使用外部样式类,比方法一要麻烦一些,也就是我们直接给spu-scroll这个组件来设置顶部间距,所以先将
方法一中修改的代码还原,然后咱们给自定义的这个组件增加一下上边距,先定义一个class:
运行你会发现木有效果。。
这里就涉及到自定义组件对于设置间距有时会无效的问题了【言外之意并非所有情况都无效】,所以这也是为啥要用这种方式实现的原因,那如何给一个自定义的组件定义一个外部样式类呢?其实在封装spu-scroll组件中就已经在lin-ui的价格组件用过了:
对于这样的属性,需要在组件的js中进行定义,如下:
接下来则需要声明该样式作用的地方,这里可以由你根据需要自由决定,这里我们将它声明在:
此时我们就可以使用这个外部样式类了,如下:
此时再运行间距就正常了,所以记住:当你在一个自定义的组件中设置普通样式如果不好使,记得使用外部样式类来尝试解决。
不过对于只有一个间距专门定义一个外部样式类感觉有点杀鸡用牛刀的感觉,所以这里不采用这种方式。
方法三:
最后还有一种办法,就是:
这样效果也是木问题的,因为对于普通的view来说使用普通的方式来设置样式肯定是木问题的。
结论:
这里还是采用第一种方式,这里也有一个原则,就是能在普通view中来设置样式就要在普通view中,除非是不得已才考虑到自定义组件上来设置,而如果在自定义组件上设置样式不生效时,记得用自定义外部样式来尝试解决。
最后感觉这个价格的文字有点大,微调一下:
改成:
运行:
另一主题实现:
概述:
接下来实现另一个主题,其实就是一张纯图,长这样:
实现:
1、主题数据获取:
这个主题其实是locationF,这个在之前已经有定义了:
此时可以回到home.js中来调用一下它:
2、图片显示:
接下来则可以将数据显示出来了,如下:
3、调整样式:
这块的样式比较简单,直接给出:
运行:
关注个人公众号,获得实时推送