小程序高级电商前端第1周走进Web全栈工程师<四>----自定义组件与Lin UI的小试牛刀

本文详细介绍如何利用LinUI Grid组件构建小程序中的分类六宫格,并深入探讨自定义组件的设计原则。

LinUI Grid组件构建分类六宫格:

效果图:

接着上一次小程序高级电商前端第1周走进Web全栈工程师<三>----首页Banner、分类六宫格继续,接下来则来实现分类的六宫格,先来回忆一下它的样子:

具体实现:

思考?

在正式实现它之前,先来思考一个问题,我们直接将布局写在home.wxml中是否好?

当然不好,因为咱们这个首页的业务是比较多的,随着业务的不断深入这里面的代码会越来越多,wxml代码一多,其它连带的像.js,.wxss都会相应的进行膨胀的,那么有什么方式能解决这样的问题么,将它自定义成一个组件既可,就像我们集成的lin-ui一样,所以有了这层的思考,接下来则将九宫格分类以组件的方式来进行实现。

自定义组件框架搭建:

咱们接下来则来学会如何在小程序中自定义组件,先新建一个文件夹:

然后再建一个具体跟咱们这个组件相关的文件夹:

然后像新建页面一样,还是回到小程序的IDE上来,因为会一次性为我们生成关联的所有文件,比较方便,如下:

这里则有一个比较好的约定给组件文件命名的方式,就是统一叫index既可,如下:

这里打开index.js瞅一眼,可以看到它跟Page是有区别的:

而页面的根结点是Page。

页面骨架编写:

引入组件:
这里先来上官网宫格 Grid | Lin UI看一下LinUi的这个九宫格组件是怎么使用的:

其中一行的个数的配置可以使用它:

 其实对于这个开源组件的核心是用到了小程序的这个特性来实现的:

其中这里会涉及到如下几个重要的生命周期函数:

上面仅做一个了解,回到正题上来,开始定义一下六宫格,既然要引用LinUi的宫格组件,则应该将它引入到咱们的组件来,在小程序中可以在这里进行引入:

那假如有N多个页面都需要引用同一个组件是不是每一个页面上都得重新用这句话来引用一遍,有没有一种全局的引入方式呢?当然,可以在这,所以也是咱们采用的方式:

而引用的语句跟在单个组件中的是一样的:

那是如何引用的呢?采用key-value的方式,如下:

而value则是我们所要使用三方开源的组件的绝对路径:

编写wxml:

约定俗成,先用view套一下,而这个view的class也一般用container来进行命名,当然叫其它名也可以,只是尽量用一个统一个习惯来命名会比较好,接下来则在里面套grid控件:

<view class="container">
    <l-grid>
        
    </l-grid>
</view>

根据官方的使用示例,接下来则需要使用grid-item:

而它又是一个组件:

所以此时则需要将它也引入进来:

此时咱们则可以来使用它了:

<view class="container">
    <l-grid>
        <l-grid-item>
            
        </l-grid-item>
    </l-grid>
</view>

而这个item应该是需要遍历生成的,所以:

<view class="container">
    <l-grid>
        <block wx:for="{{}}">
            <l-grid-item>

            </l-grid-item>
        </block>
    </l-grid>
</view>

接下来每个grid-item的是一个上下的结构:

所以此时又是一个插槽的理念,如下:

<view class="container">
    <l-grid>
        <block wx:for="{{}}">
            <l-grid-item>
                <view>
                    <image src="{{}}"></image>
                    <text>{{}}</text>
                </view>
            </l-grid-item>
        </block>
    </l-grid>
</view>

数据请求:

在目前的布局编写中:

都是需要进行数据绑定的地方。

思考:

接下来则需要绑定数据了,而要绑定数据则需要有数据嘛,所以接下来则来弄这些数据,当然也就是请求API接口喽, 这里又得进行一个思考了,目前组件里面的数据请求有两种写法:

1、直接写在组件的.js中进行:

2、还可以写在调用组件的那一个.js文件中,回到咱们这个场景也就是home.js:

那哪种方式更加的合适呢?其实应该是第二种,也就是将数据的请求逻辑写在调用方那,而不应该写在组件本身的里面,为啥?因为这样能保证组件的通用性,因为数据来源不一定就是从网络上获取,也有可能还有其它的数据源,如果将数据的请求写在了组件本身,那么这样就降低了它的灵活性了,对于组件本身而言只需要有数据展示既可,不应该让它关心数据的来源的,所以,咱们下面则开始来编写数据的请求。

API的mock搭建:

还是上Create a Free Mock API with TestApi.io中先来mock一下九宫格的数据:

其返回的JSON为:

[
    {
        "id": 1,
        "title": "服装",
        "img": "http://i1.sleeve.7yue.pro/grid/clothing.png",
        "name": null,
        "category_id": null,
        "root_category_id": 2
    },
    {
        "id": 2,
        "title": "包包",
        "img": "http://i1.sleeve.7yue.pro/grid/bag.png",
        "name": null,
        "category_id": null,
        "root_category_id": 3
    },
    {
        "id": 3,
        "title": "鞋",
        "img": "http://i1.sleeve.7yue.pro/grid/shoes.png",
        "name": null,
        "category_id": null,
        "root_category_id": 1
    },
    {
        "id": 4,
        "title": "饰品",
        "img": "http://i1.sleeve.7yue.pro/grid/jewelry.png",
        "name": null,
        "category_id": null,
        "root_category_id": 5
    },
    {
        "id": 5,
        "title": "居家",
        "img": "http://i1.sleeve.7yue.pro/grid/furniture.png",
        "name": null,
        "category_id": null,
        "root_category_id": 4
    },
    {
        "id": 6,
        "title": "工艺",
        "img": "http://i1.sleeve.7yue.pro/grid/book.png",
        "name": null,
        "category_id": null,
        "root_category_id": 24
    }
]

API的封装: 

接下来则按之前的约定,新建一个js文件:

API调用及数据绑定:

这里需要注意,如果数据是一个数组,在定义时最好不要初始化为null,而是它:

另外其实我们在setData的属性也可以不在data中进行定义,但是这样会造成这个setData的属性可以在任意的代码逻辑中进行修改,不利于代码的维护,所以一般好的习惯是定义:

好,接下来问题来了,咱们在调用方请求的数据怎么来传递给咱们的grid的组件呢? 这样搞:

对于上面的而言,由于它只是赋值了个初始值,对于只有初始值的属性还可以简写成这样:

此时咱们就可以通过home页面通过这个属性来将咱们的数据传递给组件了,具体做法是先在home页面中先将咱们的这个九宫格分类组件引进来,引入方式跟咱们组件中引用三方的LinUi的宫格组件一样,既可以在app.json中又可以在home.json中,不过由于咱们的这个九宫格组件只会在home页面使用到,所以就不放全局了,下面先在home.json中引入一下它:

此时则可以在home.wxml中来使用了,然后通过在页面中就可以将数据通过组件的属性进行数据传递了,如下:

此时则可以在组件中来使用API的数据了,如下:

此时编译运行看一下效果:

此时数据正常绑定了,只是目前的样式还没调,没有看出grid九宫格的效果而已。

编写分类九宫格样式:

container样式:

看效果图上是有padding的,如下:

所以先编写它的样式:

grid-item:

这里就有一个技巧性了,这里试想一下,假如它就是实际Grid项的宽高:

所以,这里的样式应该设置大一点,大概是这样子:

所以咱们定义一下:

设置图片的尺寸:

接下来则需要定义一下图片的大小了,所以:

此时预览下效果:

貌似完全木有看出九宫格的效果呀,这个其实在官网上已经说明了:

所以咱们定义一下:

<view class="container">
    <l-grid>
        <block wx:for="{{grid}}">
            <l-grid-item key="{{index}}" slot="{{index}}">
                <view class="grid-item">
                    <image class="img" src="{{item.img}}"></image>
                    <text>{{item.title}}</text>
                </view>
            </l-grid-item>
        </block>
    </l-grid>
</view>

此时再运行看一下:

增加虚线框:

嗯,有一个大概的样子了,不过还得细化,先来给增加一个虚线框:

此时运行发现木有看到有虚线呀,其实这里有一个关于自定义组件样式的一个规则:“不能直接对一个自定义的组件设置class,而要用它的外部样式”,啥意思?

此时需要使用外部样式类,啥叫外部样式类呢,看一下组件的官方说明:

它的外部样式类是叫"l-class", 对于LinUi的外部样式类基本都是它,当然实际可能有些组件会有多个外部样式类,具体用哪个到时根据实际组件的说明来,其实关于外部样式类在小程序的官网也有说明的:

当然在组件上使用class也是能让它生效的,像小程序的官网的这一个说明:

,只是。。不推荐这样做,所以咱们来使用一下外部样式再试一下:

再运行看一眼:

居中调整:

但是发现咱们的内容木有居中,所以再调整一下:

边框居中了,但是grid-item项木有居中:

所以同样的,也用flex布局设置一下:

运行看一下:

发现此时还是有问题,貌似感觉这个高度有点高:

其实吧不用设置高度,LinUI的宫格组件已经为我们动态计算了,所以:

再运行看一下:

文本与文本的间距:

这个比较简单,直接贴出来:

.text{
    margin-top: 6rpx;
    font-size: 24rpx;
    color: #333333;
}

最后运行看一下:

组件设计与LinUI使用的几个非常重要的原则【闲扯】:

下面来聊一聊小程序组件设计的几个重要原则,它对于我们未来用好LinUI提供的组件能够更加的得心应手。

  • 你必须在组件的灵活性与易用性之间做出一个选择,找到一个平衡点。
    越是灵活的组件,易到性就越差(简单说,就是复杂性越高);而越是简单的组件,灵活性和定制性就不够。
    如何理解,就拿咱们目前的九宫格组件来说,本身它里面是基于LinUI的宫格组件进行实现的,而咱们自己又封装了一层,那直接用LInUI的宫格组件不好么,好,但是太过于灵活,易到性上没有咱们目前经过自己的一层封装好,从home.wxml中的使用就可以看出来:

    但是!!!咱们的这个易用性反而不够通用了,也就是说咱们封装的这个九宫格只适合首页这种样式的分类,如果换其它形态的则就不通用的。 

  • 组件到底意义是什么?
    组件从三个方面:样式、骨架、业务逻辑/行为上对代码进行了封装,方便开发者在日后重用/复用样式、骨架和业务逻辑。
  • 组件必须要提供给用户的几个特点与方法:
    组件必须允许用户通过某种方法对组件进行“自定义”。不能自定义的组件或者说自定义程序很弱的组件不是一个很好的组件设计。“自定义”性通常包括:
    1、对样式的自定义。
    2、对骨架的自定义。
    3、对业务逻辑的自定义。
    而从现有的技术手段来讲,对于以上的自定义性,微信小程序有以下几个方式来支持自定义:
    1、外部样式类(样式自定义)
    2、Slot插槽(骨架自定义)
    3、业务逻辑(Behavior行为)
    但正如课程中谈到的,业务逻辑的自定义有2个问题:
    1、Behavior依然繁锁。
    2、组件的业务逻辑自定义其实某种程序上来讲,是个伪命题。
    为什么是个伪命题呢?因为组件A之所以是组件A,而不是组件B,正是由于他们独特的业务逻辑,如果改变了业务逻辑,那么组件A可能就不应该是组件A了。所以,组件对业务逻辑的自定义性是有待探讨的。
    对于组件的灵活性主要是体现在如下几点上:
    a、外部样式类
    b、Slot插槽
    c、业务逻辑,对于若干个业务逻辑一般则是用传参的方式。
  • 如果没有明确理由,不要固定高和宽:
    回到咱们的九宫格,对于grid-item咱们是可以不设置高度的,所以就不要设置:

    这样写出来的代码维护性和灵活性都是比较好的 

关注个人公众号,获得实时推送

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

webor2006

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值