原生小程序开发项目复盘

1,134 阅读8分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情

介绍原生小程序开发中常用的东西。

一、小程序结构

image.png

  • app.js: 小程序的逻辑,一般小的项目app.js中不会有太多代码,只有一些比如检测版本更新之类的(后边会说)

  • app.json 小程序公共配置

    • pages:页面的路径列表 pages的路径也就是页面的文件路径

        "pages": [
          "pages/index/index",
          "pages/my/my",
          "pages/logs/logs"
        ],
      
    • tabBar: 底部 tab 栏的表现

      • color: tab 上的文字默认颜色,仅支持十六进制颜色
      • selectedColor: tab 上的文字选中时的颜色,仅支持十六进制颜色
      • backgroundColor: tab 的背景色,仅支持十六进制颜色
      • borderStyle: tabbar 上边框的颜色, 仅支持 black / white
      • list: tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab
        • pagePath: 页面路径,必须在 pages 中先定义
        • text: tab 上按钮文字
        • iconPath: 图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。 当 position 为 top 时,不显示 icon。
        • selectedIconPath: 选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px * 81px,不支持网络图片。当 position 为 top 时,不显示 icon。
      • position: tabBar 的位置,仅支持 bottom / top
      • custom: 自定义 tabBar,(后边细说)
      "tabBar": {
          "color": "#999",
          "selectedColor": "#6576ff",
          "borderStyle": "black",
          "backgroundColor": "#fff",
          "list": [
            {
              "pagePath": "pages/index/index",
              "text": "首页",
              "iconPath": "static/home-tab@2x.png",
              "selectedIconPath": "static/home-tab-active@2x.png"
            },
            {
              "pagePath": "pages/my/my",
              "text": "我的",
              "iconPath": "static/user-tab@2x.png",
              "selectedIconPath": "static/user-tab-active@2x.png"
            }
          ]
        },
      
  • app.wxss 小程序的样式公共配置

  • pages目录:存在小程序的页面

    image.png

  • index.json:页面的配置文件

    • navigationBarBackgroundColor: 导航栏背景颜色,如 #000000
    • navigationBarTextStyle: 导航栏标题颜色,仅支持 black / white
    • navigationBarTitleText: 导航栏标题文字内容
    • navigationStyle:导航栏样式,仅支持以下值:`default 默认样式\custom` 自定义导航栏,只保留右上角胶囊按钮。参见注 2。
    • backgroundColor: 窗口的背景色
    • backgroundTextStyle: 下拉 loading 的样式,仅支持 dark / light
    • backgroundColorTop: 顶部窗口的背景色,仅 iOS 支持
    • backgroundColorBottom: 底部窗口的背景色,仅 iOS 支持
    • enablePullDownRefresh: 是否开启全局的下拉刷新
    • onReachBottomDistance:页面上拉触底事件触发时距页面底部距离,单位为 px
    • pageOrientation: 屏幕旋转设置,支持 auto / portrait / landscape
    • restartStrategy: 重新启动策略配置\
    • initialRenderingCache:页面初始渲染缓存配置,支持 static / dynamic
    • visualEffectInBackground:切入系统后台时,隐藏页面内容,保护用户隐私。支持 hidden / none
    • handleWebviewPreload: 控制预加载下个页面的时机。支持 static / manual / auto
  • static存在静态文件多指图片,但是图片不应超过200KB

二、点击事件

常用的事件

一般就是bindtap, 阻止事件冒泡用catch事件 互斥事件绑定mut-bind 事件列表

  • touchstart:手指触摸动作开始
  • touchmove:手指触摸后移动
  • touchcancel:手指触摸动作被打断,如来电提醒,弹窗
  • touchend:手指触摸动作结束
  • tap:手指触摸后马上离开
  • longpress:手指触摸后,超过350ms再离开,如果指定了事件回调函数并触发了这个事件,tap事件将不被触发
  • longtap:手指触摸后,超过350ms再离开(推荐使用longpress事件代替)
  • transitionend:会在 WXSS transition 或 wx.createAnimation 动画结束后触发
  • animationstart:会在一个 WXSS animation 动画开始时触发
  • animationiteration:会在一个 WXSS animation 一次迭代结束时触发
  • animationend:会在一个 WXSS animation 动画完成时触发
  • touchforcechange:在支持 3D Touch 的 iPhone 设备,重按时会触发

点击事件获取参数的方式

<button data-index="1" data-name='2' bindtap="handleClick">这是个点击事件</button>

能看到这是个点击事件,通过data-XXX,拿到页面的数据

js文件中使用

 handleClick (even: any) {
    const { index, name } = even.currentTarget.dataset
    console.log(index, name)
 }

image.png

三、 生命周期

image.png 这里少了个onLaunch,这个生命函数写在app.js里

然后我们看下小程序刚进入触发的函数

image.png

然后切换页面后触发的生命函数

image.png

四、页面常用标签

WXML:WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件事件系统,可以构建出页面的结构。

数据绑定

<!--wxml-->
<view> {{message}} </view>
// page.js
Page({
  data: {
    message: 'Hello MINA!'
  }
})

wx:for

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


// page.js
Page({
  data: {
    array: [1, 2, 3, 4, 5]
  }
})

条件渲染


<!--wxml-->
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>


// page.js
Page({
  data: {
    view: 'MINA'
  }
})

还有一个模板,这个后边说

input

小程序的input和vue的input稍有区别 小程序的input是通过事件绑定修改数据

  • bindinput:键盘输入时触发
  • bindfocus:输入框聚焦时触发
  • bindblur:输入框失去焦点时触发,
  • bindconfirm:点击完成按钮时触发
  • bindkeyboardheightchange:键盘高度发生变化的时候触发此事件

四、 页面间跳转

小程序api地址:developers.weixin.qq.com/miniprogram…

  • wx.switchTab:跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
  • wx.reLaunch:关闭所有页面,打开到应用内的某个页面
  • wx.redirectTo:关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
  • wx.navigateTo:保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。使用 wx.navigateBack 可以返回到原页面。小程序中页面栈最多十层。
  • wx.navigateBack:关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages 获取当前的页面栈,决定需要返回几层。
  • EventChannel:页面间事件通信通道
  • wx.navigateToMiniProgram:打开另一个小程序
  • wx.navigateBackMiniProgram:返回到上一个小程序。只有在当前小程序是被其他小程序打开时可以调用成功。注意:微信客户端 iOS 6.5.9,Android 6.5.10 及以上版本支持
  • wx.exitMiniProgram:退出当前小程序。必须有点击行为才能调用成功。 除wx.switchTab外,其他的页面都是可以传参数的

页面间通信事件

这是必须是wx.navigateTo

例如,my页面传数据到log页面中

my.js


    wx.navigateTo({
      url: '/pages/logs/logs',
      events: {
        // 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
        acceptDataFromOpenedPage: function(data) {
          console.log('acceptDataFromOpenedPage',data)
        },
        someEvent: function(data) {
          console.log('someEvent',data)
        }
      },
      success: res => {
        res.eventChannel.emit('acceptDataFromOpenerPage', { data: '我的页面的数据' })
      }
    })

log.js

const eventChannel = this.getOpenerEventChannel()
eventChannel.emit('acceptDataFromOpenedPage', {data: 'test'});
eventChannel.emit('someEvent', {data: 'test'});
// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
eventChannel.on('acceptDataFromOpenerPage', function(data) {
   console.log(data)
})

点击页面跳转,可以看到

image.png

五、分享功能

用户点击右上角转发onShareAppMessage

onShareAppMessage() {

    const promise = new Promise(resolve => {
      setTimeout(() => {
        resolve({
          title: '自定义转发标题'
        })
      }, 2000)
    })

    return {
      title: '自定义转发标题',
      path: '/page/user?id=123',
    }
}

return一个object,用于自定义收藏内容

- title:页面标题或账号名称
- path: 当前页面 path ,必须是以 / 开头的完整路径
- imageUrl:页面截图 最好是w:h=1:1
- promise:如果该参数存在,则以 resolve 结果为准,如果三秒内不 resolve,分享会使用上面传入的默认参数

除次之外还可以用button按钮转发

<button open-type="share">
   转发按钮
</button>

使用button事件时,onShareAppMessage会有参数返回,

onShareAppMessage(even) {
    if(even.from === 'button') {
        // 来自按钮转发
    }

    return {
      title: '自定义转发标题',
      path: '/page/user?id=123',
    }
}

even有三个参数:

- from:转发事件来源。 `button`:页面内转发按钮; `menu`:右上角转发菜单
- target:如果 `from` 值是 `button`,则 `target` 是触发这次转发事件的 `button`,否则为 `undefined`
- webViewUrl:页面中包含`web-view`组件时,返回当前`web-view`的url

转发朋友圈onShareTimeline()

事件处理函数返回一个 Object,用于自定义分享内容,不支持自定义页面路径,返回内容如下:

  • title: 自定义标题,即朋友圈列表页上显示的标题
  • query: 自定义页面路径中携带的参数,如 path?a=1&b=2 的 “?” 后面部分
  • imageUrl:自定义图片路径,可以是本地文件或者网络图片。支持 PNG 及 JPG,显示图片长宽比是 1:1

同时在使用分享朋友圈的时候必须调用wx.showShareMenu

wx.showShareMenu

显示当前页面的转发按钮,参数Object

  • withShareTicket:是否使用带 shareTicket 的转发[详情]
  • menus:本接口为 Beta 版本,暂只在 Android 平台支持。需要显示的转发按钮名称列表,默认['shareAppMessage']。按钮名称合法值包含 "shareAppMessage"、"shareTimeline" 两种
  • success:接口调用成功的回调函数
  • fail:接口调用失败的回调函数
  • complete:接口调用结束的回调函数(调用成功、失败都会执行)

代码:

 onLoad() {
    wx.showShareMenu({
        withShareTicket: true,
	menus: ['shareAppMessage', 'shareTimeline']
    })
  },
  onShareTimeline() {
    return {
      title: '我的页面',
      query: '/pages/my/my?id=1',
      imageUrl:''
    }
  },

image.png

收藏 onAddToFavorites


onAddToFavorites(res) {
    // webview 页面返回 webViewUrl
    console.log('webViewUrl: ', res.webViewUrl)
    return {
      title: '自定义标题',
      imageUrl: 'http://demo.png',
      query: 'name=xxx&age=xxx',
    }
  }

六、修改数据setData

常规修改数据

// wxml
<view>{{num}}</view>

// my.ts
Page({
  data: {
    num: 1,
  },
  onLoad() {
    this.setData({
      num: 2
    })
  },
})

image.png

修改对象的数据

<view>张三的岁数:{{userInfo.age}}</view>

data: {
  userInfo: {
      name: '张三',
      age: '100'
  }
},
  
this.setData({
   'userInfo.age': 1
})

image.png

修改数组

list: [
   {id: 1, label: 'label1'},
   {id: 2, label: 'label2'},
   {id: 3, label: 'label3'},
]

this.setData({
   ['list[1].label']: '我是改变的label'
})

image.png

七、获取用户信息

获取code wx.login()

wx.login({
  success (res) {
    if (res.code) {
      //发起网络请求
      wx.request({
        url: 'https://example.com/onLogin',
        data: {
          code: res.code
        }
      })
    } else {
      console.log('登录失败!' + res.errMsg)
    }
  }
})

获取用户信息 wx.getUserProfile

该api的调用必须是button按钮调用

<button open-type="getUserInfo" bindgetuserinfo="getUserProfile">获取用户信息</button>
getUserProfile() {
    // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
    wx.getUserProfile({
      desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
        console.log(res)
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    })
  },

未完待续!!!