前端【小程序】04-小程序基础篇【生命周期】【页面生命周期】【应用生命周期】【组件生命周期】

生命周期

  生命周期是一些名称固定自动执行的函数。

 页面生命周期

  文档:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#%E5%8F%82%E6%95%B0

  • onLoad 在页面加载完成时执行,只会执行 1 次,常用于获取地址参数和网络请求,页面加载时触发。一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中的参数
  • onShow 在页面处于可见状态时执行,常用于动态更新数据或状态
  • onReady 在页面初次渲染完成时执行,只会执行 1 次,常用于节点操作或动画交互等场景
  • onHide 在页面处于不见状态时执行,常用于销毁长时间运行的任务,如清理定时器

图书本地存储示例 

index.wxml

 1 <button class="button" size="mini" type="primary" bind:tap="getBooks">查询书单</button>
 2 <view class="books">
 3   <view class="item">
 4     <text>序号</text>
 5     <text>名称</text>
 6     <text>作者</text>
 7     <text>出版社</text>
 8     <text>操作</text>
 9   </view>
10   <view class="item" wx:for="{{books}}" wx:key="id">
11     <text>{{index + 1}}</text>
12     <text>{{item.bookname}}</text>
13     <text>{{item.author}}</text>
14     <text>{{item.publisher}}</text>
15     <text>删除</text>
16   </view>
17 </view>
18 
19 <!-- 本地存储 -->
20 <view class="storage">
21   <button size="mini" type="primary" bind:tap="setStorageData">存数据</button>
22   <button size="mini" type="primary" bind:tap="getStorageData">读数据</button>
23   <button size="mini" type="primary" bind:tap="removeStorageData">删数据</button>
24   <button size="mini" type="primary" bind:tap="clearStorageData">清数据</button>
25 </view>
26 
27 <view class="preview" bind:tap="onChoose">
28   <image src="{{ avatar }}" mode="aspectFill" />
29 </view>
30 
31 <!-- 搜索历史
32 <view class="history">
33   <view class="search-bar">
34     <input type="text" model:value="{{ keyword }}" />
35     <text class="label" bind:tap="onSearch">搜索</text>
36   </view>
37   <view class="title" wx:if="{{ keywords.length }}">
38     历史搜索 <text class="icon-delete" bind:tap="onClear">x</text>
39   </view>
40   <view class="keywords">
41     <navigator url="/pages/test/index" wx:for="{{ keywords }}" wx:key="*this">
42       {{ item }}
43     </navigator>
44   </view> -->

index.wxss

  1 /* pages/interface/index.wxss */
  2 .button {
  3   margin-top: 10rpx;
  4 }
  5 
  6 .books {
  7   padding: 0 20rpx;
  8   margin-top: 20rpx;
  9   border-radius: 10rpx;
 10   background-color: #fff;
 11 }
 12 
 13 .books .item {
 14   display: flex;
 15   justify-content: space-between;
 16   height: 44rpx;
 17   padding: 20rpx 0;
 18   text-align: center;
 19   border-bottom: 1rpx solid #eee;
 20 }
 21 
 22 .books .item:last-child {
 23   border-bottom: none;
 24 }
 25 
 26 .books .item text {
 27   text-overflow: ellipsis;
 28   white-space: nowrap;
 29   overflow: hidden;
 30 }
 31 
 32 .books .item text:first-child {
 33   width: 80rpx;
 34 }
 35 
 36 .books .item text:nth-child(2) {
 37   width: 180rpx;
 38 }
 39 
 40 .books .item text:nth-child(3) {
 41   width: 140rpx;
 42 }
 43 
 44 .books .item text:nth-child(4) {
 45   flex: 1;
 46 }
 47 
 48 .books .item text:last-child {
 49   width: 80rpx;
 50 }
 51 
 52 .storage {
 53   display: flex;
 54   justify-content: space-around;
 55   padding: 20rpx 0;
 56   margin-top: 20rpx;
 57   border-radius: 10rpx;
 58   background-color: #fff;
 59 }
 60 
 61 .storage button {
 62   margin: 0;
 63 }
 64 
 65 
 66 .preview {
 67   width: 200rpx;
 68   height: 200rpx;
 69   margin-top: 20rpx;
 70   border-radius: 10rpx;
 71   background-color: #fff;
 72   background-image: url(https://lotjol.github.io/static-store/enjoy-plus/images/upload.png);
 73   background-size: 80rpx;
 74   background-position: center;
 75   background-repeat: no-repeat;
 76 }
 77 
 78 .preview image {
 79   width: 100%;
 80   height: 100%;
 81 }
 82 
 83 .history {
 84   margin-top: 20rpx;
 85   padding: 30rpx 20rpx;
 86   border-radius: 10rpx;
 87   background-color: #fff;
 88 }
 89 
 90 .history .search-bar {
 91   display: flex;
 92 }
 93 
 94 .history .search-bar .label {
 95   width: 90rpx;
 96   margin-right: 10rpx;
 97   text-align: right;
 98   line-height: 70rpx;
 99 }
100 
101 .history .search-bar input {
102   flex: 1;
103   padding-left: 40rpx;
104   border-radius: 60rpx;
105 }
106 
107 .history .title {
108   display: flex;
109   justify-content: space-between;
110   margin-top: 30rpx;
111   padding-left: 20rpx;
112   font-size: 30rpx;
113 }
114 
115 .history .title .icon-delete {
116   width: 36rpx;
117   height: 36rpx;
118   text-align: center;
119   line-height: 32rpx;
120   border-radius: 50%;
121   color: #fff;
122   transform: scale(0.9);
123   background-color: #ccc;
124 }
125 
126 .history .keywords {
127   display: flex;
128   flex-wrap: wrap;
129   margin-top: 10rpx;
130   border-radius: 10rpx;
131 }
132 
133 .history .keywords navigator {
134   margin-right: 20rpx;
135   margin-top: 20rpx;
136   padding: 8rpx 28rpx;
137   border-radius: 50rpx;
138   background-color: #f7f6f7;
139   font-size: 28rpx;
140 }

index.js

  1 Page({
  2   data: {
  3     books: [],
  4     keyword:'',
  5     keywords:[]
  6   },
  7   // onSearch() {
  8   //   const keyword = this.data.keyword.trim()
  9 
 10   //   // 非空判断
 11   //   if(keyword === '') {
 12   //     return wx.showToast({
 13   //       icon:'none',
 14   //       title: '请输入搜索内容',
 15   //     })
 16   //   }
 17 
 18   //   const arr = [keyword,...this.data.keywords]
 19   //   this.setData({
 20   //     keywords:Array.from(new Set(arr)),
 21   //     keyword:''
 22   //   })
 23   // },
 24   // 调用数据接口的方法
 25   getBooks() {
 26 
 27     // 加载提示
 28     wx:wx.showLoading({
 29       title: '疯狂加载中',
 30       mask: true
 31     })
 32     // 调用小程序的 API 发起请求
 33     wx.request({
 34       url: 'https://hmajax.itheima.net/api/books',
 35       method: 'GET',
 36       data: {
 37         creator: 'zhangsan',
 38       },
 39       success: (result) => {
 40         // 更新数据,渲染页面
 41         this.setData({ books: result.data.data })
 42 
 43         // 轻提示
 44         wx.showToast({
 45           icon:'success',
 46           title: '查询成功'
 47         })
 48       },
 49       complete() {
 50         wx.hideLoading()
 51       }
 52     })
 53   },
 54   // 本地存储 - 存数据
 55   setStorageData() {
 56     // 🚨注意:小程序通过 this.data.xxx 获取 data 数据
 57     wx.setStorageSync('list', this.data.list)
 58     // 轻提示
 59     wx.showToast({ icon: 'success', title: '存储成功' })
 60 
 61     // 同步写法 - 推荐,书写简洁方便
 62     //    wx.setStorageSync('key', data)
 63     // 异步写法
 64     //    wx.setStorage({ key:'key', data: data, success(){} })
 65 
 66     // wx.setStorage({
 67     //   key: 'list',
 68     //   data: this.data.list,
 69     //   success: () => {
 70     //     wx.showToast({ icon: 'success', title: '存储成功' })
 71     //   }
 72     // })
 73   },
 74 
 75   // 本地存储 - 取数据
 76   getStorageData() {
 77     const list = wx.getStorageSync('list')
 78     console.log(list);
 79     wx.showToast({ icon: 'none', title: '读取成功,看控制台' })
 80 
 81     // 异步写法
 82     // wx.getStorage({
 83     //   key: 'list',
 84     //   success: (res) => {
 85     //     console.log(res.data)
 86     //     wx.showToast({ icon: 'none', title: '读取成功,看控制台' })
 87     //   }
 88     // })
 89   },
 90 
 91   // 本地存储 - 删数据
 92   removeStorageData() {
 93     wx.removeStorageSync('logs')
 94     wx.showToast({ icon: 'success', title: 'logs删除成功' })
 95   },
 96 
 97   // 本地存储 - 清数据 - 慎用
 98   clearStorageData() {
 99     wx.clearStorageSync()
100     wx.showToast({ icon: 'none', title: '清空了全部本地存储' })
101   },
102 
103   // 选择图片
104   async onChoose() {
105     const { tempFiles} = await wx.chooseMedia({
106       mediaType:['image'],
107       count:1,
108     })
109     // console.log(tempFiles[0].tempFilePath);
110     this.setData({
111       avatar:tempFiles[0].tempFilePath
112     })
113   }
114 })

 

应用生命周期

  App函数的文档:https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html

  • onLaunch 小程序启动时执行 1 次,常用于小程序更新,获取启动参数,获取场景值
  • onShow 小程序前台运行时执行
  • onHide 小程序后台运行时执地

开发工具中,关闭小程序,会显示场景值查找

  

App.js

 1 App({
 2   // 小程序初始化完成时触发,全局只触发一次
 3   onLaunch(options) {
 4     // 小程序启动时会执行一次,常用于获取场景值或参数
 5     console.log("onLaunch", options);
 6     console.log("场景值", options.scene);
 7     console.log("query参数", options.query);
 8   },
 9   // 小程序启动或从后台进入前台显示时
10   onShow(options) {
11     console.log("options", options);
12     console.log("场景值", options.scene);
13     console.log("query参数", options.query);
14   },
15   // 小程序从前台进入后台时,点击关闭按钮其实也会进入后台,微信会保留几分钟
16   onHide() {
17     console.log("onHide");
18   }
19 })

小程序启动后,打印日志:

  

 

小程序更新机制

  开发者在管理后台发布新版本的小程序之后,微信客户端会有若干个时机去检查本地缓存的小程序有没有新版本,并进行小程序的代码包更新。但如果用户本地有小程序的历史版本,此时打开的可能还是旧版本。

1. 启动时同步更新

  在以下情况下,小程序启动时会同步更新代码包。同步更新会阻塞小程序的启动流程,影响小程序的启动耗时。

如果更新失败或超时,为了保障小程序的可用性,还是会使用本地版本打开。

定期检查发现版本更新

  微信运行时,会定期检查最近使用的小程序是否有更新。如果有更新,下次小程序启动时会同步进行更新,更新到最新版本后再打开小程序,尽可能保证用户能够尽快使用小程序的最新版本。

用户长时间未使用小程序

  用户长时间未使用小程序时,为保障小程序版本的实时性,会强制同步检查版本更新,更新到最新版本后再打开小程序。

  若用户处于弱网环境、下载最新版本失败等情况下,仍会启动本地的较低版本。

2. 启动时异步更新

  即使启动前未发现更新,小程序每次冷启动时,都会异步检查是否有更新版本。如果发现有新版本,将会异步下载新版本的代码包。但当次启动仍会使用客户端本地的旧版本代码,即新版本的小程序需要等下一次冷启动才会使用。

开发者手动触发更新

  在启动时异步更新的情况下,如果开发者希望立刻进行版本更新,可以使用 wx.getUpdateManager API 进行处理。在有新版本时提示用户重启小程序更新新版本。

 1 // app.js
 2 App({
 3   onLaunch() {
 4     // 小程序启动时,检查更新
 5     this.checkUpdate()
 6   },
 7   checkUpdate() {
 8     // 获取版本更新管理器
 9     const updateManager = wx.getUpdateManager()
10 
11     // 检查更新结果
12     updateManager.onCheckForUpdate(function (res) {
13       // 是否有更新
14       console.log(res.hasUpdate)
15     })
16 
17     // 监听小程序有版本更新事件
18     updateManager.onUpdateReady(function () {
19       // 客户端主动触发下载(无需开发者触发下载,只需要做引导重启的提示即可)
20       wx.showModal({
21         title: '更新提示',
22         content: '新版本已经准备好,是否重启应用?',
23         success: function (res) {
24           if (res.confirm) {
25             // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
26             updateManager.applyUpdate()
27           }
28         },
29       })
30     })
31 
32     updateManager.onUpdateFailed(function () {
33       // 新版本下载失败
34       console.log("新版本下载失败")
35     })
36   },
37 })

编译设置

  

 编译然后从新进入小程序

  

 

组件生命周期

  created:组件创建时触发
     • 类似Vue 中的created
     • 不能调用this.setData
  attached:组件初始完毕时触发
    • 类似于Vue 中的mounted
    • 最常使用
  应用示例:状态栏适配
    • wx.getSystemInfoSync()   同步的方式获取系统信息,包含状态栏的高度(单位px)(statusBarHeight),系统版本,型号....

  • created 组件创建时触发,类似于 Vue 中的 created 生命周期,该生命周期中不能调用 this.setData
  • attached 组件初始化完毕时触发,类似于 Vue 中的 mounted 生命周期,该生命周期函数使用最频繁

  小程序自定义组件的生命周期需要定义在 lifetimes 中:

组件的js中添加生命周期属性

 1 // components/my-nav/my-nav.js
 2 Component({
 3  
 4   options: {
 5      // 方案1:addGlobalClass: true表示允许外部修改组件样式
 6     addGlobalClass: true,
 7     multipleSlots: true // 在组件定义时的选项中启用多slot支持
 8   },
 9   
10   // 方式2:自定义样式类
11   externalClasses: ['custom-class'],
12 
13   // 组件生命周期
14   lifetimes: {
15     // 相当于vue的created
16     // 
17     created() {
18       // 几乎不用,因为created()方法中使用this.setData()无效
19     },
20     // 相当于vue的mounted
21     attached() {
22       // 获取屏幕刘海的高度
23       const {statusBarHeight} = wx.getSystemInfoSync();
24       console.log(statusBarHeight);
25       this.setData({
26         statusBarHeight: statusBarHeight   // 将获取到的刘海高度,赋值给变量statusBarHeight
27       });
28     }
29   },
30 
31   /**
32    * 组件的属性列表
33    */
34   properties: {
35 
36   },
37 
38   /**
39    * 组件的初始数据
40    */
41   data: {
42   statusBarHeight: 0
43   },
44 
45   /**
46    * 组件的方法列表
47    */
48   methods: {
49 
50   }
51 })

组件增加行内样式来获取上面获取到的刘海高度

1 <!--components/my-nav/my-nav.wxml-->
2 <view class="navigation-bar custom-class" style="padding-top: {{ statusBarHeight }}px;">   // 刘海高度动态获取,在组件的生命周期函数中获取,单位是px,所以这里在大括号外面写上单位px
3   <view class="navigation-bar-title title-class">
4     <!-- 指定多个插槽 -->
5     <slot name="left"></slot> 自定义标题 <slot name="right"></slot>
6   </view>
7 </view>

组件的样式

 1 /* components/my-nav/my-nav.wxss */
 2 .navigation-bar {
 3   background-color: #ffffff;
 4   height: 88rpx;
 5   /* 顶部刘海预留 */
 6   padding-top: 100rpx;
 7   display: flex;
 8   justify-content: center;
 9   align-items: center;
10 }
11 
12 .navigation-bar-title {
13   font-weight: bold;
14 }

 

posted @ 2024-04-17 20:33  为你编程  阅读(45)  评论(0编辑  收藏  举报