Skip to content

uni-app Lifecycle Guide

This guide provides a detailed introduction to uni-app lifecycles, including application lifecycle, page lifecycle, and component lifecycle, to help you better understand and use uni-app.

Overview

Lifecycle refers to functions triggered at specific time points during the entire process from application creation to destruction, where developers can execute their own code logic.

uni-app Lifecycle Categories

TypeDescriptionListening Location
Application LifecycleApplication-level lifecycle functionsListen in App.vue
Page LifecyclePage-level lifecycle functionsListen in pages
Component LifecycleComponent-level lifecycle functionsListen in components

Application Lifecycle

Application lifecycle refers to functions triggered at specific time points during the process from uni-app startup to unloading. These functions are defined in App.vue.

Lifecycle Functions

FunctionDescriptionParametersUse Cases
onLaunchTriggered when application initialization is complete (triggered only once globally)options (startup parameters)Initialize app data, check updates, get user info
onShowTriggered when application starts or enters foreground from backgroundoptions (startup parameters)Restore app state, refresh data, track usage time
onHideTriggered when application enters background from foreground-Pause audio/video playback, save app state, pause timers
onErrorTriggered when application encounters runtime errorserr (error information)Error log collection, exception reporting
onUniNViewMessageListen to data sent from nvue pagesevent (message object)Receive messages from nvue pages

Application Lifecycle Example

vue
<script>
export default {
  onLaunch: function(options) {
    console.log('App Launch')
    console.log('Launch parameters:', options)
    
    // Initialize application data
    this.checkUpdate()
    this.getUserInfo()
  },
  
  onShow: function(options) {
    console.log('App Show')
    console.log('Show parameters:', options)
    
    // Restore application state
    this.resumeAudio()
    this.startTimer()
  },
  
  onHide: function() {
    console.log('App Hide')
    
    // Save application state
    this.pauseAudio()
    this.stopTimer()
  },
  
  onError: function(err) {
    console.log('App Error')
    console.error(err)
    
    // Error reporting
    this.reportError(err)
  },
  
  methods: {
    checkUpdate() {
      // Update checking logic
      uni.getUpdateManager && uni.getUpdateManager().onCheckForUpdate((res) => {
        if (res.hasUpdate) {
          console.log('New version found')
        }
      })
    },
    
    getUserInfo() {
      // Get user info logic
      uni.getUserInfo({
        success: (res) => {
          console.log('User info:', res.userInfo)
        }
      })
    },
    
    resumeAudio() {
      // Resume audio playback logic
      const audioContext = uni.createInnerAudioContext()
      audioContext.play()
    },
    
    pauseAudio() {
      // Pause audio playback logic
      const audioContext = uni.createInnerAudioContext()
      audioContext.pause()
    },
    
    startTimer() {
      // Start timer logic
      this.timer = setInterval(() => {
        console.log('Timer task executed')
      }, 60000)
    },
    
    stopTimer() {
      // Stop timer logic
      if (this.timer) {
        clearInterval(this.timer)
        this.timer = null
      }
    },
    
    reportError(err) {
      // Error reporting logic
      uni.request({
        url: 'https://api.example.com/error-report',
        method: 'POST',
        data: {
          error: err.toString(),
          timestamp: Date.now()
        }
      })
    }
  }
}
</script>

Page Lifecycle

Page lifecycle refers to functions triggered at specific time points during the process from uni-app page loading to unloading. These functions are defined in the page's vue file.

Page Lifecycle Execution Order

Page Load → onLoad → onShow → onReady
Page Switch → onHide → Other Page → onShow
Page Unload → onUnload

Lifecycle Functions

FunctionDescriptionParametersTrigger Timing
onLoadTriggered when page loadsoptions (page parameters)When page loads, triggered only once
onShowTriggered when page shows-When page shows/enters foreground
onReadyTriggered when page initial rendering is complete-When page initial rendering is complete, triggered only once
onHideTriggered when page hides-When page hides/enters background
onUnloadTriggered when page unloads-When page unloads
onPullDownRefreshTriggered on pull-to-refresh-When user pulls down to refresh
onReachBottomTriggered when reaching bottom-When page scrolls to bottom
onPageScrollTriggered on page scrollObjectWhen page scrolls
onTabItemTapTriggered on tab clickObjectWhen clicking tab (tabBar pages only)

Page Lifecycle Details

onLoad - Page Load

Trigger Timing: Triggered when page loads, only once

Parameters: options (data passed from previous page)

Use Cases:

  • Get page parameters
  • Initialize page data
  • Make network requests for initial data
javascript
onLoad: function(options) {
  console.log('Page load complete')
  console.log('Page parameters:', options)
  
  // Initialize page data
  this.productId = options.id
  this.loadProductDetail(options.id)
}

onShow - Page Show

Trigger Timing: Triggered when page shows/enters foreground

Use Cases:

  • Refresh page data
  • Restore page state
  • Start audio/video playback
javascript
onShow: function() {
  console.log('Page show')
  
  // Refresh cart data
  this.refreshCartData()
  // Restore page state
  this.resumeVideoPlay()
}

onReady - Page Rendering Complete

Trigger Timing: Triggered when page initial rendering is complete, only once

Use Cases:

  • Get page elements
  • Initialize complex components like charts
  • Execute operations that need to be performed after page rendering
javascript
onReady: function() {
  console.log('Page initial rendering complete')
  
  // Get page elements
  const query = uni.createSelectorQuery()
  query.select('#chart').boundingClientRect(data => {
    // Initialize chart
    this.initChart(data.width, data.height)
  }).exec()
}

onHide - Page Hide

Trigger Timing: Triggered when page hides/enters background

Use Cases:

  • Pause audio/video playback
  • Save page state
  • Pause timers and other power-consuming operations
javascript
onHide: function() {
  console.log('Page hide')
  
  // Pause video playback
  this.pauseVideo()
  // Save edit state
  this.saveEditState()
  // Pause timer
  clearInterval(this.timer)
}

onUnload - Page Unload

Trigger Timing: Triggered when page unloads

Use Cases:

  • Clean up page resources
  • Cancel network requests
  • Close long connections
javascript
onUnload: function() {
  console.log('Page unload')
  
  // Clean up resources
  this.disposeChart()
  // Cancel network requests
  this.cancelRequest()
  // Close socket connection
  this.closeSocket()
}

onPullDownRefresh - Pull to Refresh

Trigger Timing: Triggered when user pulls down to refresh

Use Cases:

  • Refresh page data
  • Reload resources

Note: Need to configure enablePullDownRefresh as true in pages.json

javascript
onPullDownRefresh: function() {
  console.log('User pull down refresh')
  
  // Reload data
  this.loadData().then(() => {
    // Stop pull-to-refresh after data loading is complete
    uni.stopPullDownRefresh()
  })
}

onReachBottom - Reach Bottom

Trigger Timing: Triggered when page scrolls to bottom

Use Cases:

  • Load more data
  • Implement pagination loading

Note: Can configure onReachBottomDistance in pages.json to set trigger distance

javascript
onReachBottom: function() {
  console.log('Page scrolled to bottom')
  
  if (!this.isLoading && !this.isEnd) {
    this.isLoading = true
    this.page++
    this.loadMoreData().then(() => {
      this.isLoading = false
    })
  }
}

onPageScroll - Page Scroll

Trigger Timing: Triggered when page scrolls

Parameters: Object containing scrollTop property, indicating the distance the page has scrolled vertically (in px)

Use Cases:

  • Implement sticky effects
  • Show/hide back-to-top button
  • Adjust UI based on scroll position

Note: Triggered frequently, consider throttling

javascript
onPageScroll: function(e) {
  // Use throttle function to handle scroll events
  if (this.scrollTimer) return
  
  this.scrollTimer = setTimeout(() => {
    this.scrollTimer = null
    // Show/hide back-to-top button based on scroll position
    this.showBackToTop = e.scrollTop > 100
    // Implement sticky effect
    this.isFixed = e.scrollTop > 200
  }, 100)
}

onTabItemTap - Tab Click

Trigger Timing: Triggered when clicking tab, only exists in tabBar pages

Parameters: Object containing pagePath, text, index properties

Use Cases:

  • Track tab click events
  • Refresh page when clicking current tab
  • Custom tab click behavior
javascript
onTabItemTap: function(e) {
  console.log('Tab clicked', e)
  
  // If clicking current tab, refresh page
  if (e.index === this.currentTabIndex) {
    this.refreshPage()
  }
  // Track click event
  this.reportTabClick(e.index)
}

Complete Page Lifecycle Example

vue
<template>
  <view class="page">
    <view class="content">
      <text class="title">Page Lifecycle Example</text>
      <view class="data-area">
        <text>Data: {{ dataList.length }} items</text>
      </view>
      <view class="button-area">
        <button type="primary" @click="refreshData">Refresh Data</button>
      </view>
    </view>
    
    <view class="list-area">
      <view v-for="(item, index) in dataList" :key="index" class="list-item">
        {{ item.name }}
      </view>
    </view>
    
    <view class="loading" v-if="isLoading">Loading...</view>
    
    <view class="back-to-top" v-if="showBackToTop" @click="backToTop">
      <text class="back-icon">↑</text>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      dataList: [],
      page: 1,
      isLoading: false,
      isEnd: false,
      showBackToTop: false,
      scrollTimer: null,
      productId: ''
    }
  },
  
  // Page load
  onLoad(options) {
    console.log('Page load', options)
    this.productId = options.id || ''
    this.loadData()
  },
  
  // Page show
  onShow() {
    console.log('Page show')
    this.refreshCartData()
  },
  
  // Page rendering complete
  onReady() {
    console.log('Page initial rendering complete')
    const query = uni.createSelectorQuery()
    query.select('.content').boundingClientRect(data => {
      console.log('Content area height:', data.height)
    }).exec()
  },
  
  // Page hide
  onHide() {
    console.log('Page hide')
    this.savePageState()
  },
  
  // Page unload
  onUnload() {
    console.log('Page unload')
    if (this.scrollTimer) {
      clearTimeout(this.scrollTimer)
    }
  },
  
  // Pull to refresh
  onPullDownRefresh() {
    console.log('Pull to refresh')
    this.page = 1
    this.isEnd = false
    this.loadData().then(() => {
      uni.stopPullDownRefresh()
    })
  },
  
  // Reach bottom
  onReachBottom() {
    console.log('Load more')
    if (!this.isLoading && !this.isEnd) {
      this.loadMoreData()
    }
  },
  
  // Page scroll
  onPageScroll(e) {
    if (this.scrollTimer) return
    this.scrollTimer = setTimeout(() => {
      this.scrollTimer = null
      this.showBackToTop = e.scrollTop > 100
    }, 100)
  },
  
  methods: {
    // Load initial data
    loadData() {
      this.isLoading = true
      return new Promise((resolve) => {
        setTimeout(() => {
          this.dataList = Array.from({length: 20}, (_, i) => ({
            id: i + 1,
            name: `Product ${i + 1}`
          }))
          this.isLoading = false
          resolve()
        }, 1000)
      })
    },
    
    // Load more data
    loadMoreData() {
      if (this.page >= 5) {
        this.isEnd = true
        return Promise.resolve()
      }
      
      this.isLoading = true
      return new Promise((resolve) => {
        setTimeout(() => {
          const moreData = Array.from({length: 20}, (_, i) => ({
            id: this.dataList.length + i + 1,
            name: `Product ${this.dataList.length + i + 1}`
          }))
          this.dataList = [...this.dataList, ...moreData]
          this.page++
          this.isLoading = false
          resolve()
        }, 1000)
      })
    },
    
    // Refresh data
    refreshData() {
      this.page = 1
      this.isEnd = false
      this.loadData()
    },
    
    // Refresh cart data
    refreshCartData() {
      console.log('Refresh cart data')
    },
    
    // Save page state
    savePageState() {
      console.log('Save page state')
      uni.setStorageSync('pageState', {
        scrollTop: this.scrollTop,
        page: this.page
      })
    },
    
    // Back to top
    backToTop() {
      uni.pageScrollTo({
        scrollTop: 0,
        duration: 300
      })
    }
  }
}
</script>

<style scoped>
.page {
  padding: 20px;
}

.content {
  margin-bottom: 20px;
}

.title {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 10px;
}

.data-area {
  margin: 10px 0;
  color: #666;
}

.button-area {
  margin: 15px 0;
}

.list-area {
  margin-top: 20px;
}

.list-item {
  padding: 15px;
  border-bottom: 1px solid #eee;
  background-color: #fff;
}

.loading {
  text-align: center;
  padding: 15px;
  color: #999;
}

.back-to-top {
  position: fixed;
  right: 20px;
  bottom: 30px;
  width: 40px;
  height: 40px;
  background-color: rgba(0, 0, 0, 0.5);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  z-index: 999;
}

.back-icon {
  font-size: 20px;
}
</style>

Component Lifecycle

uni-app component lifecycle follows Vue component lifecycle and also supports uni-app page lifecycle.

Vue 2 Component Lifecycle

LifecycleDescriptionUse Cases
beforeCreateBefore component instance is createdComponent options object is created, but instance is not yet created
createdComponent instance is createdInitialize data, call APIs, etc.
beforeMountBefore component mountingTemplate is compiled but not yet mounted to DOM
mountedComponent mounting completeGet DOM elements, initialize third-party libraries, etc.
beforeUpdateBefore component updateData is updated but DOM is not yet re-rendered
updatedComponent update completeDOM operations after update
beforeDestroyBefore component destructionClean up timers, cancel event listeners, etc.
destroyedComponent destruction completeComponent instance is destroyed

Vue 3 Component Lifecycle

LifecycleDescriptionVue 2 EquivalentUse Cases
setupComponent initializationbeforeCreate/createdEntry point for Composition API
onBeforeMountBefore component mountingbeforeMountPreparation work before mounting
onMountedComponent mounting completemountedGet DOM elements, initialize third-party libraries, etc.
onBeforeUpdateBefore component updatebeforeUpdatePreparation work before update
onUpdatedComponent update completeupdatedDOM operations after update
onBeforeUnmountBefore component unmountingbeforeDestroyClean up timers, cancel event listeners, etc.
onUnmountedComponent unmounting completedestroyedComponent instance is destroyed

Component Lifecycle Examples

Vue 2 Component Example

vue
<template>
  <view class="component">
    <text>{{ message }}</text>
    <button @click="updateMessage">Update Message</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      message: 'Initial message',
      timer: null
    }
  },
  
  beforeCreate() {
    console.log('beforeCreate: Before component instance is created')
  },
  
  created() {
    console.log('created: Component instance is created')
    // Initialize data
    this.initData()
  },
  
  beforeMount() {
    console.log('beforeMount: Before component mounting')
  },
  
  mounted() {
    console.log('mounted: Component mounting complete')
    // Start timer
    this.timer = setInterval(() => {
      console.log('Timer running...')
    }, 2000)
  },
  
  beforeUpdate() {
    console.log('beforeUpdate: Before component update')
  },
  
  updated() {
    console.log('updated: Component update complete')
  },
  
  beforeDestroy() {
    console.log('beforeDestroy: Before component destruction')
    // Clean up timer
    if (this.timer) {
      clearInterval(this.timer)
    }
  },
  
  destroyed() {
    console.log('destroyed: Component destruction complete')
  },
  
  methods: {
    initData() {
      console.log('Initialize data')
    },
    
    updateMessage() {
      this.message = 'Updated message: ' + Date.now()
    }
  }
}
</script>

Vue 3 Component Example

vue
<template>
  <view class="component">
    <text>{{ message }}</text>
    <button @click="updateMessage">Update Message</button>
  </view>
</template>

<script setup>
import { 
  ref, 
  onBeforeMount, 
  onMounted, 
  onBeforeUpdate, 
  onUpdated, 
  onBeforeUnmount, 
  onUnmounted 
} from 'vue'

// Reactive data
const message = ref('Initial message')
let timer = null

// Lifecycle hooks
console.log('setup: Component initialization')

onBeforeMount(() => {
  console.log('onBeforeMount: Before component mounting')
})

onMounted(() => {
  console.log('onMounted: Component mounting complete')
  // Start timer
  timer = setInterval(() => {
    console.log('Timer running...')
  }, 2000)
})

onBeforeUpdate(() => {
  console.log('onBeforeUpdate: Before component update')
})

onUpdated(() => {
  console.log('onUpdated: Component update complete')
})

onBeforeUnmount(() => {
  console.log('onBeforeUnmount: Before component unmounting')
  // Clean up timer
  if (timer) {
    clearInterval(timer)
  }
})

onUnmounted(() => {
  console.log('onUnmounted: Component unmounting complete')
})

// Methods
function updateMessage() {
  message.value = 'Updated message: ' + Date.now()
}

// Initialize data
function initData() {
  console.log('Initialize data')
}

// Execute initialization
initData()
</script>

Lifecycle Best Practices

Usage Recommendations

RecommendationDescription
Use lifecycle appropriatelyChoose appropriate lifecycle hooks based on different business needs, avoid executing complex operations in unnecessary hooks
Avoid blocking renderingAvoid executing time-consuming operations in lifecycle hooks like onLoad and onShow, which may block page rendering
Resource managementClean up resources like timers and event listeners in onUnload and beforeDestroy
Data fetchingPage data fetching is recommended in onLoad rather than onShow to avoid duplicate requests
State restorationRestore page state in onShow, such as audio/video playback state

Common Issues and Solutions

1. Data Not Refreshing When Returning to Page

Problem: Navigate from page A to page B, then return to page A, but page A data is not refreshed.

Cause: When returning to previous page, onShow is triggered instead of onLoad.

Solutions:

  1. Refresh data in onShow
  2. Use page stack management to refresh data when returning
  3. Use global event bus, trigger event after B page operation is complete, A page listens to event and refreshes data
javascript
// Page A
onShow() {
  // Check if returning from page B
  const pages = getCurrentPages()
  if (pages.length > 1 && pages[pages.length - 1].route.includes('pageA')) {
    this.refreshData()
  }
}

// Or use global events
onLoad() {
  uni.$on('updateData', () => {
    this.refreshData()
  })
}

onUnload() {
  uni.$off('updateData')
}

// After page B operation is complete
uni.$emit('updateData')

2. Page Lifecycle Execution Order Issues

Problem: Unclear about the execution order of various lifecycles during page navigation.

Solution: Understand the lifecycle execution order during page navigation:

  • A page navigates to B page: A.onHideB.onLoadB.onShowB.onReady
  • B page returns to A page: B.onUnloadA.onShow

3. Relationship Between Component and Page Lifecycles

Problem: Unclear about the execution order and relationship between component and page lifecycles.

Solution: Understand the relationship between component and page lifecycles:

  • Page loading: Page onLoadComponent beforeCreateComponent createdComponent beforeMountComponent mountedPage onShowPage onReady
  • Page unloading: Page onUnloadComponent beforeDestroyComponent destroyed

4. Memory Leak Issues

Problem: After page navigation, resources like timers and event listeners from the original page are not released, causing memory leaks.

Solution: Clean up resources when page unloads:

javascript
onLoad() {
  // Create timer
  this.timer = setInterval(() => {
    this.doSomething()
  }, 1000)
  
  // Add event listener
  uni.$on('customEvent', this.handleEvent)
}

onUnload() {
  // Clean up timer
  if (this.timer) {
    clearInterval(this.timer)
    this.timer = null
  }
  
  // Remove event listener
  uni.$off('customEvent', this.handleEvent)
}

Summary

uni-app lifecycle is an important concept in development. Correctly understanding and using lifecycle can:

  • Improve application performance
  • Avoid memory leaks
  • Optimize user experience
  • Simplify state management

It's recommended to choose appropriate lifecycle hooks based on specific business needs in actual development and pay attention to timely resource cleanup.

一次开发,多端部署 - 让跨平台开发更简单