微信小程序-04

122 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情

表单

​ 小程序中提供了与网页类似的表单组件,如 form、input、button等,它是收集用户信息的重要手段。

组件

​ 使用小程序提供的表单相关组件定义界面,如常见的登录/注册:

<form>
  <view class="item">
    <label for="">姓名: </label>
    <input type="text" />
  </view>
  <view class="item">
    <label for="">密码:</label>
    <input type="text" password />
  </view>
  <view class="item">
    <button type="primary">保存</button>
  </view>
</form>

​ 但是在小程序也有一些组件与网页是不一致的,如复选框、单选框、下拉选择框等。

<form>
  .....
  <!-- 单选 -->
  <view class="item">
    <label for="">性别: </label>
    <radio-group>
      <radio value="男" /><radio value="女" /></radio-group>
  </view>
	<!-- 复选 -->
  <view class="item">
    <label for="">爱好: </label>
    <checkbox-group>
      <checkbox value="睡大觉" />睡大觉
      <checkbox value="写代码" />写代码
    </checkbox-group>
  </view>
  <!-- 下拉选择框 -->
  <view class="item">
    <label for="">级别: </label>
    <picker range="{{['初级', '中级', '高级']}}">
      <view class="grade">初级</view>
    </picker>
  </view>
  <view class="item">
    <button type="primary">保存</button>
  </view>
</form>

​ 小程序中 input 组件属性 type 的取值没有 password , 要表示密码类型需要设置 password 属性。

数据

​ 表单的重要职责是收集用户填写的数据,然后将数据提交到服务端处理。

<!-- 监听表单提交 -->
<form bind:submit="send">
  <view class="item">
    <label for="">姓名: </label>
    <input type="text" name="username" />
  </view>
  <view class="item">
    <label for="">密码:</label>
    <input type="text" name="password" password />
  </view>
  <view class="item">
    <!-- 指定 form-type -->
    <button type="primary" form-type="submit">保存</button>
  </view>
</form>

​ 提交表单时需要为 button 组件,指定 form-type 属性,值为 submit 时才会触发表单的提交(submit)事件,同时 input 组件必须指定 value 属性并赋值,目的是方便后端接收。

Page({
  data: {},
  send: function (ev) {
    // 通过 ev.detail 获取 input 组件中的数据
    console.log(ev.detail);
  }
})

​ 对于单选框、复选框、下拉框则要通过监听 change 事件,才能获取表单中的数据。

<form>
  .....
  <!-- 单选 -->
  <view class="item">
    <label for="">性别: </label>
    <radio-group bind:change="getRadioValue">
      <radio value="男" /><radio value="女" /></radio-group>
  </view>
	<!-- 复选 -->
  <view class="item">
    <label for="">爱好: </label>
    <checkbox-group bind:change="getCheckboxValue">
      <checkbox value="睡大觉" />睡大觉
      <checkbox value="写代码" />写代码
    </checkbox-group>
  </view>
  ......
  <view class="item">
    <button type="primary">保存</button>
  </view>
</form>

​ 单选框、复选框、下拉框组件的数据保存在组件的 value 属性中,所以要获取组件中的数据必须指定 value 属性。

Page({
  
  // ...
  getRadioValue: function (ev) {
    // 通过事件对象 ev.detail 获取单选框数据
    console.log(ev);
  },

  getCheckboxValue: function (ev) {
    // 通过事件对象 ev.detail 获取复选框数据
    console.log(ev);
  }
  
})

自定义组件

​ 小程序内置提供了许多组件,同时也允许开发者根据业务需要自定义组件。

创建

​ 如下所示,自定义组件的构成与小程序页面的构成一致。

├── app.js ...................................................... 小程序入口文件
├── app.json .................................................... 小程序全局配置
├── app.wxss .................................................... 小程序全局样式
├── components .................................................. 组件目录
|   ├── header
|   |   ├── index.js ............................................ 组件header业务逻辑
|   |   ├── index.json .......................................... 组件header配置
|   |   ├── index.wxml .......................................... 组件header布局结构
|   |   └── index.wxss .......................................... 组件header布局样式
|   └── list
├── pages ....................................................... 所有页面目录
│   ├── index ................................................... index页面目录
│   │   ├── index.js ............................................ index页面业务逻辑
│   │   ├── index.wxml .......................................... index页面布局结构
│   │   └── index.wxss .......................................... index页面布局样式
│   └── logs .................................................... logs页目录
├── project.config.json ......................................... 开发工具配置文件
└── utils ....................................................... 公共逻辑
    └── util.js ................................................. 实用工具

​ 小程序自定义组件与页面主要有两点不同:

  1. 组件对应的 .js 文件中调用 Component 函数
// 调用 Components 函数,由小程序内置提供
Component({
  properties: {
    
  },
  data: {
    
  },
  methods: {
    
  }
})
  1. 组件对应的 .json 文件中,配置 component: true
{
  conponent: true,
  usingComponents: {}
}

应用

​ 自定义组件可以应用到页面中,也可以被其它组件引用。假设首页需要应用自定义的 header 组件:

// pages/index/index.json
{
  usingComponents: {
    // 导入自定义组件
    header: '../../components/header/index'
  }
}
<!-- pages/index/index.wxml -->
<view class="box">
   <!-- 应用自定义组件 -->
  <header />
</view>

逻辑

// components/header/index.js
Component({
  // 为自定义的组件添加属性
  properties: {
    list: {
      // 属性的数据类型
      type: String,
      // 属性的默认值
      value: 'Hi~'
    }
  },
  
  // 组件初始数据
  data: {
    msg: 'Hello World!'
  },
  
  // 组件方法,可用于事件监听回调函数
  methods: {
    sayHi: function () {
      console.log('Hi~');
      this.setData({
        msg: '你好,世界!'
      })
    }
  }
})

​ 调用 Component 函数时:

  1. 通过 properties 为组件定义属性,需要同时指定类型和默认值
  2. 通过 data 为组件初始化数据
  3. 通过 methods 为组件定义事件回调,这与页面中定义事件回调是不一致

通信

​ 自定义组件有自已的作用域,然而在实际开发中,父子组件之间的数据传递是不可避免的。

  1. 子组件访问父组件,通过将子组件的属性赋值为父组件的数据实现
<!-- pages/index/index.wxml -->
<view class="box">
   <!-- 应用自定义组件 -->
  <header list="{{navs}}" />
</view>
// pages/index/index.js
Page({
  // 父组件中的数据
  data: {
    navs: ['首页', '登录', '注册']
  }
})
  1. 父组件访问子组件
  • 父组件自定义事件
<!-- pages/index/index.wxml -->
<view class="box">
   <!-- 应用自定义组件 -->
  <header list="{{navs}}" bind:myevent="mycallback" />
</view>
// pages/index/index.js
Page({
  // 父组件中的数据
  data: {
    navs: ['首页', '登录', '注册']
  },
  // 自定义事件的回调
  mycallback: function () {
    console.log('我是父组件中的回调函数...');
  }
})
  • 子组件触发父组件自定义事件
// components/header/index.js
Component({
  // ...
  
  // 组件方法,可用于事件监听回调函数
  methods: {
    sayHi: function () {
      console.log('Hi~');
      this.setData({
        msg: '你好,世界!'
      })
      
      // 调用 triggerEvent 来触发父组件的自定义事件 myevent
      // 并且将 {name: '小明', age: 18} 做为参数,传给父组件自定义事件的回调函数
      this.triggerEvent('myevent', {name: '小明', age: 18});
    }
  }
})

​ 以上是小程序中自定义组件的基本用法,除此之外还有更多高级特性

Vant Weapp

​ Vant Weapp 是移动端 Vue 组件库 Vant 的小程序版本,两者基于相同的视觉规范,提供一致的 API 接口,助力开发者快速搭建小程序应用。

快速上手

  1. 安装
# 通过 npm 安装
npm i vant-weapp -S --production
  1. 构建npm

打开微信开发者工具,点击 工具 ==> 构建 npm,并勾选 使用 npm 模块 选项,构建完成后,即可引入组件

  1. 导入组件

以 Button 组件为例,只需要在app.jsonindex.json中配置 Button 对应的路径即可。如果你是通过下载源代码的方式使用 vant-weapp,请将路径修改为项目中 vant-weapp 所在的目录。

// app.json
"usingComponents": {
  "van-button": "vant-weapp/button"
}

导入组件后,可以在 wxml 中直接使用组件

<van-button type="primary">按钮</van-button>

组件演示

  1. Loading 加载
  2. Notify 消息提示
  3. Overlay 遮罩层
  4. Dialog 弹出框
  5. ...

F2

F2 是一个专注于移动,开箱即用的可视化解决方案,完美支持 H5 环境同时兼容多种环境(Node, 小程序,Weex),完备的图形语法理论,满足你的各种可视化需求,专业的移动设计指引为你带来最佳的移动端图表体验。

快速上手

  1. 安装
npm i @antv/f2-canvas
  1. 构建

打开微信开发者工具,点击 工具 ==> 构建 npm,并勾选 使用 npm 模块 选项,构建完成后,即可引入组件

  1. 导入组件
{
  "usingComponents": {
    "ff-canvas": "@antv/f2-canvas"
  }
}

导入组件后,可以在 wxml 中直接使用组件, 其中 opts 是一个我们在 index.js 中定义的对象,必设属性

<ff-canvas id="column-dom" canvas-id="column" opts="{{ opts }}"></ff-canvas>
  1. 绘制图表
import F2 from '@antv/wx-f2';

let chart = null;

function initChart(canvas, width, height, F2) {
  // 图表数据(也可通过请求后端获得)
  const data = [
    { year: '1951 年', sales: 38 },
    { year: '1952 年', sales: 52 },
    { year: '1956 年', sales: 61 },
    { year: '1957 年', sales: 145 },
    { year: '1958 年', sales: 48 },
    { year: '1959 年', sales: 38 },
    { year: '1960 年', sales: 38 },
    { year: '1962 年', sales: 38 },
  ];
  
  // 实例化图表
  chart = new F2.Chart({
    el: canvas,
    width,
    height
  });
	
  // 配置图表数据
  chart.source(data, {
    sales: {
      tickCount: 5
    }
  });
  
  chart.interval().position('year*sales');
  chart.render();
  return chart;
}

Page({
  data: {
    // 图表参数
    opts: {
      onInit: initChart
    }
  }
});

注:必须为 ff-canvas 组件设置宽高尺寸。

日历

​ 一个非常好用的小程序日历组件。

  1. 下载并解压缩,拷贝 calendar 文件到小程序项目下
  2. 导入组件
{
  "usingComponents": {
    "calendar": "/component/calendar/index"
  }
}

在 wxml 中引入组件

<calendar />