微信小程序组件开发

##从视图层出发,逐个分析功能的实现。篇幅可能有点长,主要是放了代码,所以看起来会特别长,建议可以先把代码敲一遍下来以后,配合文字一起看,效果会更好。这是我在掘金看的一篇文章,然后照着敲了一篇,然后自己在写一遍的同时记录下了这篇文章,其中一些逻辑方法我都尽可能的简单化举例模拟。其中踩的坑确实花了好几个小时才理解,如果你看到了这篇文章,希望你能坚持读下去,也希望能帮助到你。

一、需求分析

1、我们需要一个按钮,当点击以后会弹出消息框

2、详细框内的内容自定义

3、左右按钮内容自定

4、左右按钮点击以后触发的回调函数

二、代码实现

1、按钮一般都是button标签实现,配置信息可以根据需求选择,一般会选择配置按钮背景颜色,而配置背景颜色的标签选用 type,具体参考小程序文档。

2、给button绑定一个事件,微信小程序里提供了两个绑定接口:bindcatch,后面加上绑定的事件,中间可以用隔开或者连着写都是可以的,而bindcatch的区别在于bind不可以阻止事件冒泡,而catch可以阻止事件冒泡。

3、到当前页面对应的js文件中写书绑定的方法。绑定的方法写什么?既然是写组件,那么使用的肯定是组件写好的方法,这些方法提供外部调用,所以可以称它们为公有方法。而绑定的函数执行的就是组件提供的公有方法,所以下一步就是写组件的公有方法。

4、怎么在微信小程序里面写一个组件?良好的习惯是先创建一个目录来存放所有的组件,目录下在创建各个子目录来存放开发的组件。微信小程序分为了pages目录utils目录app小程序的配置文件,而开发的组件需要用到小程序给我们提供的Component构造器,目录名字可以用components。在该目录下在创建一个子目录来存放我们弹窗的组件,命名自定义。最后新建page页

弹窗UI

wxml:
<view class='pop_container' hidden='{{isShow}}'>    //最外层容器
  <view class='pop_mark'></view>     //遮罩层
  <view class='pop_content'>         //中间弹窗
    <view class='pop_title'>{{title}}</view>    //弹窗标题
    <view class='pop_desc'>{{desc}}</view>      //弹窗内容描述
    <view class='pop_button'>                   //弹窗左右按钮
      <view class='pop_btn' catchtap="_cancelEvent">{{cancelText}}</view>     //左边取消按钮
      <view class='pop_btn' catchtap="_confirmEvent">{{confirmText}}</view>    //右边确定按钮
    </view>
  </view>
</view>
wxss:
/* components/dialog/dialog.wxss */
.pop_mark{
  position: fixed;
  z-index: 100;
  background-color: rgba(000, 000,000, 0.3);
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}
.pop_content{
  width: 80%;
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%);
  text-align: center;
  background-color: #fff;
  overflow: hidden;
  border-radius: 5px;
  z-index: 110;
}
.pop_title{
  font-size: 18px;
  padding: 15px 15px 5px;
}
.pop_desc{
  padding: 15px 15px 5px;
  min-height: 40px;
  font-size: 16px;
  line-height: 1.3;
  word-wrap: break-word;
  word-break: break-all;
  color: #999999;
}
.pop_button{
  display: flex;
  align-items: center;
  position: relative;
  line-height: 45px;
  font-size: 17px;
}
.pop_button::before{
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  height: 1px;
  border-top: 1px solid #d5d5d6;
  color: #d5d5d6;
  transform-origin: 0 0;
  transform: scaleY(0.5);
}
.pop_btn{
  display: block;
  flex: 1;
  position: relative;
  -webkit-tap-highlight-color: rgba(000, 000, 000, 0);
}
.pop_btn:nth-of-type(1){
  color: #353535;
}
.pop_btn:nth-of-type(2){
  color: #3cc51f;
}
.pop_btn:nth-of-type(2)::after{
  content:"";
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  bottom: 0;
  border-left: 1px solid #D5D5D6;
  color: #D5D5D6;
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
  -webkit-transform:scaleX(0.5);
  transform: scaleX(0.5);
}

这里UI界面中涉及到一个hidden属性,每个组件都是默认拥有hidden属性的,作用就和字面意思一样,隐藏。如果属性值为true,就是隐藏,如果为false,就是不隐藏。UI已经写好了,后面就要开始写逻辑层代码了,而自定义组件的JS需要写在component构造器里面,所以我们需要删除js文件里面默认的配置信息,component构造器可以指定组件的属性、数据、方法等。这里参考小程序里的page构造器来理解。接下来,就应该是配置书写逻辑层的代码了。

逻辑层

数据绑定

首先从弹窗UI分析该要写哪些东西,应该配置哪些属性,组件有哪些方法。从上到下来分析,页面内容利用数据绑定即可完成。下意识的就会去page对象里寻找data属性进行配置。但前面已经把page构造器整个删除了,而使用component构造器,而里面的内容是需要自己书写的,所以需要手动添加data属性。但是,不是所有的数据绑定都写在data里的,这里还需要思考,书写的组件属性是可自定义的。

<view class='pop_container' hidden="{{isShow}}">    //最外层容器

hidden就是组件提供的属性名,属性值由我们选择。而开发的组件肯定有一些数据是提供给外部配置的,而这部分可配置的属性,则放在properties里配置,它和data一样都是配置绑定数据,data是配置不可修改的数据,而properties是配置可修改的数据。官方文档是这样介绍properties的:

定义段 类型 是否必填 描述
properties Object Map 组件的对外属性,是属性名到属性设置的映射表

合理分析,然后在data和properties里配置绑定的数据。slot表示占位符,详情可参考这边文章微信小程序 slot 插槽使用

data:{
    isShow:true,
  },
options:{
    multipleSlots:true   //在组件定义时的选项中启用多slot支持
  },
  properties:{
    /**
     * 配置可自定义属性
     */
    title:{        //属性名
      type:String,           //属性值类型,这里是必须要定义的
      value:"学习自定义组件"    // 属性值
    },
    desc:{
      type:String,
      value:"自定义一个弹出窗口"
    },
    cancelText:{
      type:String,
      value:"确定"
    },
    confirmText:{
      type:String,
      value:"取消"
    }
  },

当配置好以后需要编译查看视图时,发现并没有展示demo,因为还没有把组件引入首页,同时还需要配置json数据。

自定义组件配置信息

1、在当前组件页的json文件里打开自定义组件功能

{
  "usingComponents": {},  //这里是默认自带的,表示引入组件或者插件的路由
  "component":true    //自定义组件声明,默认是false,自定义组件时需要修改为true
}

2、在使用自定义组件的页面json中声明自定义组件的名字和路由。例如在主页引入自定义组件,就到index.json中配置文件

{
  "usingComponents": {      //使用的自定义组件
    "dialog":"/components/dialog/dialog"     //key是自定义的组件名字,可以随便声明,value为路由
  }
}

3、在页面中插入自定义的组件,其中可以配置自定义的属性值。类似title、content等都是自定义组件时放在properties中绑定的数据,是可以修改的。注意结束要使用闭合标签

4、在js文件中获取组件的实例,后面我们要调用组件提供的方法。在生命周期为onready的函数内去获取组件的实例。点击按钮以后执行组件提供的方法。

 onReady: function(){
    this.pop = this.selectComponent("#dialog")
  },
  show(){
    this.pop.showDialog()
  }
定义私有方法和公有方法

按照UI层的思路,首先需要定义外部使用的公有方法,来显示遮罩。

methods:{
    /**
     * 公有方法
     * 外部调用showDialog方法显示遮罩
     */
    showDialog(){
      this.setData({
        isShow:!this.data.isShow
      })
    },
    /**
     * 隐藏遮罩,这里为什么归为公有方法,是因为可能会在外部调用该方法隐藏窗口
     */
    hideDialog(){
      this.setData({
        isShow:!this.data.isShow
      })
    },

其次弹窗上有两个按钮,所以也需要两个方法。一般情况下,点击两个按钮都会隐藏弹框,但是两个按钮在被点击以后都会触发回调函数,至于触发什么回调函数,可由实际场景来写。这里我们在两个方法里使用小程序提供的triggerEvent方法来创建一个事件。

 

    /**
     * 私有方法
     * 该方法只是组件使用,所以称为私有方法,私有方法在命名上通常会以_开头。
     */
    _cancelEvent(){
      this.triggerEvent("cancelEvent");
    },

    _fonfirmEvent(){
      this.triggerEvent("confirmEvent");
    }
  },

创建事件是什么鬼?不要慌,接着读下去,你就懂了。首先理解什么是事件,比如点击事件tap,当监听到tap行为时就会触发事件绑定的方法。而创建一个事件可以理解为自定义一个事件,然后监听自定义的事件是否出现,如果出现了 这个事件,就执行绑定的函数。

引用到例子中,弹窗有两个按钮,“确定”与“取消”,当这两个按钮被点击后都会执行不同的回调函数,这时,我们就可以选择在这两个按钮被点击的时候创建属于它们自己的事件,然后在调用的时候监听这个事件是否被触发,如果触发了,就执行什么方法,这个方法可以在使用场景也自定义。也就是说,在组件里绑定一个点击事件,当在组件上点击了按钮,就会创建我们自定义的事件,而这时外部就会检测到创建的事件,然后执行方法。

最后完善组件上监听的事件,整个组件就算完成了。完整的代码在我的github上。

  cancel(){
    this.pop.hideDialog();
    wx.showToast({
      title: '我已经学会了',
    });
  },
  confirm(){
    this.pop.hideDialog();
    wx.showToast({
      title: '加油,在看一遍就会了',
      icon:"loading"
    })
  }

三、总结

为什么需要自定义组件,自定义组件的适用场景有哪些呢?目前阶段,就我自己的理解来说,就是把一些复用性比较高的UI组件封装到一起,当在次调用的时候直接使用自定义的组件而无需重复在写一遍相同的代码,同时也保证其可维护性。举个栗子,在之前写过的一些业务小程序中,每个bar的顶部都是同一个轮播,虽说提供的swiper组件已经很方便了,但是中间的配置内容也是很多的。如果每个bar页面都复制粘贴一遍,那简直就是浪费时间,和浪费内存。这里说一点,小程序开发完成以后上传大小是受限的,你超过那个限制大小是没有办法上传的。这时就可以选择自定义轮播UI,需要用到的时候直接调用自定义的组件。记得当时写的时候为了熟悉代码,我都是手写的,并没有复制粘贴,回忆起来真的恶心,当时也在想可不可以类似js封装组件一样封装后直接调用,奈何那时太菜也不会。现在学习了以后,打算在自定义一个图片放大缩小的组件,权当练习了。代码依旧会放在我的github上。

陈健的个人博客,记录生活所见所感、学习笔记。专注于Web前端_SEO教程_读书心得。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

返回主页看更多
狠狠的抽打博主 支付宝 扫一扫