微信小程序「进阶一」

376 阅读6分钟

微信小程序开发框架

1.基本概念:

微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验,更准确的说法是, **小程序可以视为只能用微信打开和浏览的网站,**

小程序和网页的技术模型是一样的,用到的 JavaScript 语言和 CSS 样式也是一样的,只是网页的 HTML 标签被稍微修改成了 WXML 标签,所以,小程序页面本质上就是网页。

2.项目结构:

    |- app.json 小程序静态配置(页面,导航...)
    |- app.js 小程序初始化
    |- pages 页面目录
    	|- home 
    		|- home.wxml 微信页面
    		|- home.js 页面实例(生命周期,初始化数据...)

3.配置:

.json 后缀的 JSON 配置文件

.wxml 后缀的 WXML 模板文件

.wxss 后缀的 WXSS 样式文件

.js 后缀的 JS 脚本逻辑文件

4.生命周期:

Page({
/** 页面初始化数据 */
  data: {},
/** 监听页面加载 */
  onLoad(options) {},
/** 监听页面初次渲染完成 */
  onReady() {},
/** 监听页面显示 */
  onShow() {},
/** 监听页面隐藏 */
  onHide() {},
/** 监听页面卸载 */
  onUnload() {},
/** 监听用户下拉动作 */
 onPullDownRefresh() {},
/** 页面上拉触底事件的处理函数 */
  onReachBottom() {},
/** 用户点击右上角分享 */
 onShareAppMessage() {}
})

微信小程序组件

  1. 视图容器:

    名称功能常用备注
    image图片视图
    view视图容器
    page-container页面容器小程序如果在页面内进行复杂的界面设计(如在页面内弹出半屏的弹窗、在页面内加载一个全屏的子页面等),用户进行返回操作会直接离开当前页面,不符合用户预期,预期应为关闭当前弹出的组件
    swiper滑动视图容器轮播图
    scroll-view可滚动视图容器
    root-portal脱离文档流
    movable-area可移动区域
  2. 基础内容:

    名称功能常用
    icon图标组件
    progress进度条
    rich-text富文本
    selection局部文本选区
    text文本
  3. 表单组件:

    名称功能
    button按钮
    checkbox多选项目
    checkbox-group多项选择器,内部由多个checkbox组成
    editor富文本编辑器,可以对图片、文字进行编辑
    form表单
    input输入框
    keyboard-accessory设置 input / textarea 聚焦时键盘上方 cover-view / cover-image 工具栏视图
    label用来改进表单组件的可用性
    picker从底部弹起的滚动选择器
    picker-view嵌入页面的滚动选择器
    picker-view-column滚动选择器子项
    radio单选项目
    radio-group单项选择器,内部由多个 radio 组成
    slider滑动选择器
    switch开关选择器
    textarea多行输入框
  4. 导航:

    ** 名称**功能
    functional-page-navigator仅在插件中有效,用于跳转到插件功能页
    navigator页面链接
  5. 媒体组件:

    ** 名称**功能
    audio音频
    camera系统相机
    channel-live小程序内嵌视频号直播组件,展示视频号直播状态和封面,并无弹窗跳转至视频号
    channel-video小程序内嵌视频号视频组件,支持在小程序中播放视频号视频,并无弹窗跳转至视频号
    image图片
    live-player实时音视频播放(v2.9.1 起支持同层渲染
    live-pusher实时音视频录制(v2.9.1 起支持同层渲染
    video视频(v2.4.0 起支持同层渲染
    voip-room多人音视频对话

微信小程序指南

微信小程序路由

/** 保留当前页面,跳转到某个页面 */
wx.navigateTo({
  url: '/pages/target/target'
})

/** 关闭当前页面,跳转到某个页面 */
wx.redirectTo({
  url: '/pages/target/target'
})

/** 跳转到 tabBar 页面 并关闭其他非tabBar页面 */
wx.switchTab({
  url: '/pages/tabBarPage/tabBarPage'
})

/** 关闭所有页面,打开到某个页面 */
wx.reLaunch({
  url: '/pages/target/target'
});

/** 传递参数 */
wx.navigateTo({
  url: '/pages/target/target?name=John&age=30'
})

目标页面接收参数

Page({
  onLoad: function(options) {
    console.log(options.name)
    console.log(options.age)  
  }
})

模块化module.exports

在微信小程序中,可以使用 module.exports 和 require 来实现模块化开发,通过模块化,可以将代码拆分成多个文件,方便管理和复用如:

假设我们有一个工具函数模块 `utils.js`可以将其定义为一个独立的模块:
/** 
@file utils.js
*/
function formatTime(date) {
  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();
  const hour = date.getHours();
  const minute = date.getMinutes();
  const second = date.getSeconds();

  return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':');
}

function formatNumber(n) {
  n = n.toString();
  return n[1] ? n : '0' + n;
}

/** 导出模块 */
module.exports = {
  formatTime: formatTime
};

使用模块:

/** 在需要使用该模块的页面或其他模块中,可以通过 require 引入: */
const utils = require('../../utils/utils.js');
Page({
  onLoad: function() {
    const currentTime = utils.formatTime(new Date());
    console.log(currentTime); // 输出格式化后的当前时间
  }
});
  • 列表渲染
<view wx:for="{{array}}"> {{item}} </view>
Page({
  data: {
    array: [1, 2, 3, 4, 5]
  }
})
  • 条件渲染
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
Page({
  data: {
    view: 'MINA'
  }
})
  • WXML template 模版

    在微信小程序中,WXML 模板(template)可以用于定义可复用的代码片段。通过使用模板,可以提高代码的复用性和可维护性。模板类似于函数,可以在不同的地方调用,并传递不同的参数。

/** 
* @file index.wxml
* name 属性为模板命名
*/
<template name="itemTemplate">
  <view class="item">
    <text>{{name}}</text>
    <text>{{value}}</text>
  </view>
</template>

/** 
* 使用模版 
* is属性指定模板名称
*/
<import src="path/to/template.wxml" />

<view wx:for="{{items}}" wx:key="name">
  <template is="itemTemplate" data="{{...item}}" />
</view>

Page({
  data: {
    items: [
      { name: 'Item 1', value: 'Value 1' },
      { name: 'Item 2', value: 'Value 2' },
      { name: 'Item 3', value: 'Value 3' }
    ]
  }
});
  • WXSS

官方文档:developers.weixin.qq.com/miniprogram…

获取界面上的节点信息

在微信小程序中,可以使用 wx.createSelectorQuery 来获取界面上的节点信息。wx.createSelectorQuery 提供了一种方式,可以在页面中选择节点并获取其布局位置和其他信息

/** 获取单个节点 */
<view id="myView" class="my-view">Hello, WeChat Mini Program!</view>
/** 获取多个节点 */
<view class="my-view">View 1</view>
<view class="my-view">View 2</view>
<view class="my-view">View 3</view>

<button bindtap="getNodeInfo">Get Node Info</button>

Page({
  getNodeInfo: function() {
    const query = wx.createSelectorQuery();
    query.select('#myView').boundingClientRect(function(rect) {
      console.log(rect);
      // rect 包含节点的布局信息
      // rect.width, rect.height, rect.top, rect.left, rect.right, rect.bottom
    }).exec();
  }
});

Page({
  getNodesInfo: function() {
    const query = wx.createSelectorQuery();
    query.selectAll('.my-view').boundingClientRect(function(rects) {
      console.log(rects);
      // rects 是一个数组,包含每个节点的布局信息
      rects.forEach(function(rect) {
        console.log(rect);
        // rect.width, rect.height, rect.top, rect.left, rect.right, rect.bottom
      });
    }).exec();
  }
});

组件间的通信

目录:

image.png

引入子组件:

{
  "usingComponents": {
    "my-component": "/components/my-component/my-component"
  }
}

父组件可以通过属性(props)向子组件传递数据:

/** 父组件 pagespages/index */
<child-component 
	/** 传递变量 */
	message="Hello from parent!" 
	/** 传递事件 */
	bind:customEvent="handleCustomEvent"  
/>
Page({
  data: {
    message: 'Hello from parent!'
  },
  handleCustomEvent: function(e) {
    /** 获取全局状态 */
    const app = getApp();
    /** ======== */
    console.log(e.detail); 
  }
});

子组件:

/** 子组件 components/child-component */
/** .json */
{
  "component": true
}
/** .wxml */
<view>{{message}}</view>
<button bindtap="sendEvent">Send Event</button>
/** .js */
const sharedBehavior = require('../../behaviors/shared-behavior.js');
Component({
  /** 可以实现组件间的代码复用和通信 */
  behaviors: [sharedBehavior],
  /** 子组件私有变量 */
  data: {},
  /** 接收参数 */
  properties: {
    message: {
      type: String,
      value: ''
    }
  },
  /** 子组件生命周期 */
  lifetimes: {
    /** 组件实例进入页面节点树时触发 */
    attached: () => {},
    /** 组件实例刚刚被创建时触发 */
    created:() => {},
    /** 组件布局完成后触发 */
    ready:() => {},
    /** 组件实例被移动到节点树的另一个位置时触发 */
    moved:() => {},
    /** 组件实例被从页面节点树移除时触发 */
    detached:() => {},
  },
  methods: {
    sendEvent: function() {
  		/** 访问父组件传递的参数 */
      const parentText = this.data.text;
      /** 调用父组件事件 */
      this.triggerEvent('customEvent', { message: 'Hello from child!' });
    }
  }
});

behavior管理状态:

/** shared-behavior.js */
module.exports = Behavior({
  data: {
    sharedData: 'Hello from behavior!'
  },
  methods: {
    sharedMethod: function() {
      console.log('This is a shared method');
    }
  }
});

插槽solt

/** 子组件 */
<view class="container">
  <slot name="header"></slot>
  <slot name="content"></slot>
  <slot name="footer"></slot>
</view>
/** 父组件 */
<view>
  <my-component>
    <view slot="header">Header content from parent</view>
    <view slot="content">Main content from parent</view>
    <view slot="footer">Footer content from parent</view>
  </my-component>
</view>