微信小程序

本文介绍了微信小程序的开发流程,包括注册小程序账号、项目目录结构、页面注册、全局和页面配置、生命周期、自定义组件、视图层WXML、API使用以及路由参数。特别讨论了wxParse插件用于解析HTML内容,以及如何处理用户信息和请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说在前面

1、小程序没有DOM对象,一切基于组件化。

2、在小程序中 ,通过App()来注册一个小程序 ,通过Page()来注册一个页面。

3、微信官方提供屏幕适配方案:

  • 以iPhone6的物理像素为标准 750,
  • iPhone6中 1rpx = 1物理像素 = 0.5px
  • 1rpx = (设备视口宽度 / 750 )px
  • 默认已经做了 viewport 适配处理

 

开发前准备

注册小程序账号

我这里注册的是个人账号。微信小程序官网教程写得很详细,亦或参考文章

注册好之后,回到你的小程序首页=>开发=>开发设置,就能看到你的AppID

然后再下载开发工具。

基本项目目录

快速创建一个带模板的项目,项目目录大致如下

 

注册程序及页面

注册程序app.js

项目根目录必须有一个 app.js 文件,文件内必须调用 App() 函数,就是创建一个根实例。

  • App() 函数用来注册一个小程序。接受一个 Object参数,其指定小程序的生命周期回调等。
  • App() 必须在 app.js 中调用,必须调用且只能调用一次。不然会出现无法预期的后果。

实例代码放在后面生命周期那段

注册页面

Page(Object) 函数用来注册一个页面。接受一个 Object 类型参数,其指定页面的初始数据、生命周期回调、事件处理函数等。

实例代码放在后面生命周期那段

 

配置

全局配置app.json

项目根目录下的 app.json 文件用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。

最基础配置

{
  "pages":[
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "samfung demo2",
    "navigationBarTextStyle":"black"
  }
}

页面配置

每一个小程序页面也可以使用.json文件来对本页面的窗口表现进行配置。

页面的配置只能设置 app.json 中部分 window 配置项的内容,页面中配置项会覆盖 app.json 的 window 中相同的配置项。

基本配置

{
  "navigationBarBackgroundColor": "#ffffff",
  "navigationBarTextStyle": "black",
  "navigationBarTitleText": "微信接口功能演示",
  "backgroundColor": "#eeeeee",
  "backgroundTextStyle": "light"
}

详细配置选项请看官方文档

 

生命周期

小程序的生命周期app.js

官方文档上的参数说明:

属性类型描述触发时机
onLaunchFunction生命周期回调—监听小程序初始化小程序初始化完成时(全局只触发一次)
onShowFunction生命周期回调—监听小程序显示小程序启动,或从后台进入前台显示时
onHideFunction生命周期回调—监听小程序隐藏小程序从前台进入后台时
onErrorFunction错误监听函数小程序发生脚本错误,或者 api 调用失败时触发,会带上错误信息
onPageNotFoundFunction页面不存在监听函数小程序要打开的页面不存在时触发,会带上页面信息回调该函数
其他Any开发者可以添加任意的函数或数据到 Object参数中,用 this 可以访问

 

示例代码:

App({
  //小程序初始化完成时触发,全局只触发一次  
  onLaunch(options) {
    // Do something initial when launch.
  },
  //小程序启动,或从后台进入前台显示时触发
  onShow(options) {
    // Do something when show.
  },
  //小程序从前台进入后台时触发
  onHide() {
    // Do something when hide.
  },
  //小程序发生脚本错误或 API 调用报错时触发
  onError(msg) {
    console.log(msg)
  },
  globalData: 'I am global data'
})

页面的生命周期

常见的几个钩子函数:

onLoad(Object query): 页面加载,一个页面只会调用一次。可以在 onLoad 的参数中获取打开当前页面路径中的参数。

onShow(): 页面显示,每次打开页面都会调用一次。

onReady(): 页面初次渲染完成,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。

onHide(): 页面隐藏,当navigateTo或底部tab切换时调用。

onUnload(): 页面卸载,当redirectTo或navigateBack的时候调用。

Page({
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    console.log('页面加载')
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    console.log('页面初次渲染完成')
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    console.log('页面显示')
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    console.log('页面隐藏')
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    console.log('页面卸载')
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

 

自定义组件

小程序也可以自定义组件,写过 Vue 组件就很容易理解。

组件生命周期

created() 组件实例化,但节点树还未导入,因此这时不能用setData从父组件传来的属性值这时还是空值

attached() 节点树完成,可以用setData渲染节点,但无法操作节点,从父组件传来的属性值这时可以获取

ready() 组件布局完成,这时可以获取节点信息,也可以操作节点

moved() 组件实例被移动到树的另一个位置

detached() 组件实例从节点树中移除

 

组件

这里只是随便列举几个,更多的组件请看官方文档

<image>

按比例拉伸,加入mode属性

<image src='xxx' mode='widthFix'></image>

<navigator>

页面跳转,去掉点击时样式,加入hover-class属性

<navigator url='/pages/index/index' hover-class="none"></navigator>

<swiper>

<swiper indicator-dots="{{true}}"
autoplay="{{true}}" interval="{{3000}}" duration="{{500}}" circular="{{true}}">
  <block wx:for="{{imgUrls}}" wx:key="{{index}}">
    <swiper-item>
      <image src="{{item}}" class="slide-image" width="355" height="150"/>
    </swiper-item>
  </block>
</swiper>

<input>

<input class='search-input' type='text' confirm-type='search' value='{{searchStr}}' placeholder='请输入关键字' bindconfirm='handleSearch'/>

<button>转发

<button class='forward-btn' open-type='share'>
  <text class='iconfont icon-tubiao212' style='font-size:36px;'></text>
</button>

去掉 button 边框

button::after {
  border: none
}

<text>

加入 decode 属性可解析空格符

<text class='info' decode='{{true}}'>{{userInfo.nickName}}&emsp;1分钟前</text>

 

 

视图层wxml

数据绑定{{}}

跟vue差不多,小程序里绑定数据也是用双大括号 {{}} 将变量或者简单表达式包起来。比如:

<!-- message在Page()中data定义 -->
<view>{{ message }}</view>

与vue不同的在于组件属性动态绑定,比如:

<!-- Vue -->
<img :src="imgSrc"/>

<!-- 小程序 -->
<image src="{{imgSrc}}"></image>

列表渲染wx:for

与Vue类似,小程序在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item。,相当于Vue中的 v-for="(item, index) in array"

<view wx:for="{{array}}">{{index}}: {{item.message}}</view>

block wx:for

也可以将 wx:for 用在<block/>标签上,以渲染一个包含多节点的结构块。例如:

<block wx:for="{{[1, 2, 3]}}">
  <view>{{index}}:</view>
  <view>{{item}}</view>
</block>

模板template

WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。与Vue中定义功能组件相似

创建模板文件,可以不需要js和json文件

template/list-item.wxml  注意要给template命名

<!--pages/template/list-item.wxml-->
<template name="listItemTmp">
  <view class='list-item-container'>
    <image src='{{item}}'></image>
    <text>列表{{index+1}}</text>
  </view>
</template>

template/list-item.wxss

/* pages/template/list-item.wxss */
.list-item-container{
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 20rpx 0;
}

在需要使用该模板的 wxml 以及 wxss 文件中引入

<!-- wxml -->
<import src="/pages/template/list-item.wxml" />
/* wxss */
@import '/pages/template/list-item.wxss';

在页面中使用该模板,注意,这里往模板传入一个字符串数组的 item 以及 index

Page({
  data: {
    listImgUrl: [
      'http://ws2.sinaimg.cn/large/69f81679gy1fxp41ocoxzj21400u0awg.jpg',
      'http://ws2.sinaimg.cn/large/69f81679gy1fxp41ocoxzj21400u0awg.jpg',
      'http://ws2.sinaimg.cn/large/69f81679gy1fxp41ocoxzj21400u0awg.jpg',
      'http://ws2.sinaimg.cn/large/69f81679gy1fxp41ocoxzj21400u0awg.jpg',
      'http://ws2.sinaimg.cn/large/69f81679gy1fxp41ocoxzj21400u0awg.jpg'
    ]
  }
})
<import src="/pages/template/list-item.wxml" />

<view>
  <block wx:for="{{listImgUrl}}" wx:key="{{index}}">
    <template is="listItemTmp" data="{{item, index}}" />
  </block>
</view>

最后列表渲染效果,没样式,很随意

 

解析html内容--wxParse

都知道小程序是基于组件化的,并不能直接识别 html 内容,如果我们要显示如博客文章这样的 html 内容是就需要第三方插件 wxParse 。

使用方法很简单,首先去到 wxParse 项目地址,下载项目代码,然后将 wxParse 整个文件夹拷贝到你的小程序根目录下

然后在需要解析渲染 html 的wxml和wxss页面中分别引入

<!-- wxml -->
<import src="/wxParse/wxParse.wxml" />
/* wxss */
@import '/wxParse/wxParse.wxss';

js代码

onLoad: function (options) {
  let htmlStr = `<h2>第一篇文章</h2>
  <img src="http://ws2.sinaimg.cn/large/69f81679gy1fxp41ocoxzj21400u0awg.jpg"><br>
  <a href="http://fengyongru.com">hello</a>
  <p>Sam</p>`
  const that = this;
  // wxParse已经setData了
  WxParse.wxParse('article', 'html', htmlStr, that)
}

wxml

<!-- wxml -->
<import src="/wxParse/wxParse.wxml" />
<template is="wxParse" data="{{wxParseData: article.nodes}}"></template>

使用过程中遇到一个问题,就是在 wxParse 里 img 的宽高可能会写死了,这是自己写的 img 样式并不起作用,于是我就简单粗暴的修改 wxParse/wxParse.wxml 文件,让 img 标签宽度100%,如下

<template name="wxParseImg">
  <image class="{{item.classStr}} wxParse-{{item.tag}}" data-from="{{item.from}}" data-src="{{item.attr.src}}" data-idx="{{item.imgIndex}}" src="{{item.attr.src}}" mode="aspectFit" bindload="wxParseImgLoad" bindtap="wxParseImgTap" mode="widthFix" style="width:100%"
  />
</template>

 

API

获取用户信息wx.getUserInfo(object)

注意:此接口有调整,使用该接口将不再出现授权弹窗,请使用 <button open-type="getUserInfo"></button> 引导用户主动进行授权操作。

  • 当用户未授权过,调用该接口将直接报错
  • 当用户授权过,可以使用该接口获取用户信息

判断是否授权

wx.getSetting({
  success: res => {
    console.log(res)
    // 如果已授权
    if (!res.authSetting['scope.userInfo']) {
        ...
    }
  }
})

需要获取用户信息的页面

// 需要获取用户信息的页面
onLoad: function (options) {
  // 获取用户信息
  wx.getUserInfo({
    success: res => {
      // 如果已经授权了
      console.log('获取用户信息成功', res.userInfo)
      this.setData({
        userInfo: res.userInfo
      })
    },
    fail: () => {
      console.log('获取用户信息失败');
      // 如果没授权则跳转到用户授权页面
      wx.navigateTo({
        url: '/pages/getUserInfo/getUserInfo',
      })
    }
  })
}

用户授权页面wxml

<button open-type="getUserInfo" bindgetuserinfo="handleGetUserInfo">授权登录</button>

用户授权页面js

handleGetUserInfo(e){
   //此处授权得到userInfo
   console.log(e.detail.userInfo);
   //接下来写业务代码

   // 如果允许授权则返回刚才的页面
   if(e.detail.userInfo){
      wx.navigateBack({
        delta: 1
      })
   }
}

发送请求wx.request(Object)

微信小程序默认是发起 https 请求,如果想要发起 http 请求,点击开发工具的详情,然后再勾选“不校验域名

wx.request({
  url: 'http://localhost:8080/lala',
  method: 'GET',
  success: res => {
    console.log(res)
  }
})

本地存储wx.setStorage(Object)

这里结合用户授权处理,用户授权后将用户信息保存

if(e.detail.userInfo){    //如果用户授权了
  wx.setStorage({    //存储用户信息
    key: 'userInfo',
    data: e.detail.userInfo,
    success: res => {          
      wx.navigateBack({    //跳回上一页
        delta: 1
      })
    }
  })
}

获取

wx.getStorage({
  key: 'userInfo',
  success: res => {
    console.log(res);
  }
})

 

返回上一页并且刷新上一页的数据

有时候我们会有这样的需求,比如说,去到授权页面,授权之后返回上一页但这是上一页的数据并不会被刷新,就无法判断是否已经授权,除非你手动 onLoad 。解决办法:可以在当前页面通过 getCurrentPages() 获取上一页的实例对象,这时你就可以刷新上一页的数据或者触发上一页的方法。

let pages = getCurrentPages();
if(pages.length > 1){
  let beforePage = pages[pages.length - 2];
  let currentPage = pages[pages.length - 1];
  // 直接修改上一页的数据
  beforePage.setData({
    userInfo: xxx
  })
  // 触发上一页的方法
  beforePage.xxx()
  // 返回上一页
  wx.navigateBack({
    delta: 1
  })

}

 

路由参数

小程序中可以用 <navigator> 标签跳转,也可以用 wx.navigateTo() 或 wx.redirectTo() 进行路由跳转。这里用 <navigator> 演示:

跳转到 detail 页面,带参数 articleId

<navigator url='/pages/detail/detail?articleId={{index}}' class='article container' wx:for="{{listImgUrl}}" wx:key="{{index}}">
  <template is="listItemTmp" data="{{item, index}}" />
</navigator>

然后路由参数在 detail 页面钩子函数 onLoad(options) 中获取

onLoad: function (options) {
  console.log(options)
}

控制台打印

 

 

页面内选项卡效果    微信小程序动态绑定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值