微信

微信小程序原生自定义组件开发实战

2017-11-07  本文已影响227人  dkvirus

2017.11月初期待已久的原生小程序自定义组件功能已经发布,此次发布版本为 1.6.3,尽管此前有模板<template>和开源 wx-parse 工具也可以一定程度上复用代码,但相比此次原生小程序推出的组件化编程,都略有不足。话不多说,通过动手写一个组件来熟悉组件化编程带来的便利。

写在前面的话:

微信官网虽然提供了许多组件,但实际应用时仍感觉稍显疲软,如消息提示框只提供了成功与加载两种状态,那么如果失败了如何提示?还有模态框只有简单的 title 和 content 属性,内部并不支持自定义 wxml,等等,作者将工作中用到的微信组件文档中没有的 UI 自定义封装了一些,有需要的可以看下:wx-ui (持续补充中)

一、开发前准备

  1. 目前自定义组件相关特性处于公测阶段。如果需要使用相关特性,请确认在项目选项中已勾选“预览/上传时使用新特性”;
  2. 小程序基础库从 1.6.3才开始支持组件化编程,在此之前先升级开发工具,选择高于1.6.3版本的基础库来体验组件化编程。
  3. 微信小程序官方组件文档。 建议先看一遍,在跑一遍下方的示例代码。
image.png

二、概述

1. 目标组件

常见的价格加减组件,当设置值小于最小值时,减号 - 不可点击,当设置值大于最大值时,加好不可点击,效果如下:

price组件.gif

2. 组件化开发需要注意两点

tips: 第一遍看可能有点绕,建议将代码 copy 到开发工具跑一遍,在对照着下方的解释去理解会事半功倍。

三、价格组件实例

写一个组件,在页面中使用它。

1. 书写价格组件 price

1)组件页面 price.wxml

price 组件的页面显示。

<view class="quantityViewStyle">
  <view class="minusStyle" bindtap="minus" style="color:{{num==min?'#DADADA':white}}">-</view>
  <view class="inputViewStyle">
    <input class="inputStyle" value="{{num}}" type="number" bindblur="onInputBlur"/>
  </view>
  <view class="plusStyle" bindtap="plus" style="color:{{num==max?'#DADADA':white}}">+</view>
</view>

2)组件样式 price.wxss

price 组件的样式文件。

.quantityViewStyle {
  display:flex;
  border:0rpx solid #DADADA;
  border-radius:6rpx;
  width: 220rpx;
}
.minusStyle {
  height:58rpx;
  width:60rpx;
  border-right:0rpx solid #DADADA;
  display:flex;
  justify-content:center;
  align-items:center;
}
.plusStyle {
  height:58rpx;
  width:60rpx;
  display:flex;
  justify-content:center;
  align-items:center;
}
.inputViewStyle {
  height:58rpx;
  width:100rpx;
  border-right:0rpx solid #DADADA;
}
.inputStyle {
  width:80rpx;
  height:54rpx;
  text-align:center;
  font-size:26rpx;
  background:white;
}

3)组件逻辑 price.js

Component({
  properties: {
    // 这里定义了innerText属性,属性值可以在组件使用时指定
    num: {
      type: Number,
      value: 5,
    },
    min: {
      type: Number,
      value: 0,
    },
    max: {
      type: Number,
      value: 10
    }
  },
  methods: {
    // 加法
    plus: function () {
      // 加值小于最大值,才允许加法运算
      var num = this.data.num + 1;
      if (num <= this.data.max) {
        this.setData({
          num: num
        })
        this.triggerEvent('custom', { value: num })
      }
    },
    // 减法
    minus: function () {
      // 减值大于最小值,才允许减法运算
      var num = this.data.num - 1;
      if (num >= this.data.min) {
        this.setData({
          num: num
        })
        this.triggerEvent('custom', { value: num })
      }
    },
    // 文本框失去焦点事件,判断输入值是否为数字
    onInputBlur: function (e) {
      var value = e.detail.value;
      if (isNaN(value)) {
        // 不是数字,直接置为最小值
        this.setData({num: this.data.min})
      } else {
        // 是数字,输入值大于最大值,置为最大值,同理最小值
        if (value > this.data.max) {
          this.setData({ num: this.data.max })
        } else if (value < this.data.min) {
          this.setData({ num: this.data.min })
        }
      }
    }
  }
})

4)组件配置 price.json

声明 price 是个组件。

{
  "component": true
}

2. 在页面中使用组件

{
  "usingComponents": {
    "component-tag-name": "path/to/the/custom/component"
  }
}

1)页面 index.wxml

<view style="display: flex;flex-direction: row;justify-content: space-between;padding: 0 20rpx;">
  <view>¥26.3</view>
  <!-- 以下是对一个自定义组件的引用 price -->
  <price  num="{{price}}" bindcustom="onPageInputChange"/> 
  <view>{{price}}</view>
</view>

2)页面逻辑 index.js

Page({
  data: {
    price: 5
  },
 
  onPageInputChange: function (e) {
    this.setData({ price: e.detail.value})
  }
})

3)配置文件 index.json

声明使用组件 price。

{
  "usingComponents": {
    "price": "../price/price"
  }
}

4)app.json

配置 index 页面。

{
  "pages":[
    "pages/index/index"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle":"black"
  }
}
上一篇 下一篇

猜你喜欢

热点阅读