uni-app

1,331 阅读5分钟

一、页面生命周期函数

uni-app中,页面的生命周期函数与原生小程序的生命周期函数类似,但也有一些差异。以下是一些常用的页面生命周期函数及其功能介绍:

  1. onLoad(options):

    • 生命周期函数,在页面加载时触发。
    • options参数包含页面跳转所带来的参数。
    onLoad(options) {
      console.log('页面加载时触发');
      console.log('参数:', options);
    }
    
  2. onShow():

    • 生命周期函数,在页面显示时触发。
    • 当页面被打开、切换到前台时都会触发。
    onShow() {
      console.log('页面显示时触发');
    }
    
  3. onReady():

    • 生命周期函数,在页面初次渲染完成时触发。
    • 表示页面已经准备好,可以与视图层进行交互。
    onReady() {
      console.log('页面初次渲染完成时触发');
    }
    
  4. onHide():

    • 生命周期函数,在页面隐藏时触发。
    • 当页面被切换到后台时触发。
    onHide() {
      console.log('页面隐藏时触发');
    }
    
  5. onUnload():

    • 生命周期函数,在页面卸载时触发。
    • 当页面被关闭或跳转到其他页面时触发。
    onUnload() {
      console.log('页面卸载时触发');
    }
    
  6. onPullDownRefresh():

    • 监听用户下拉刷新事件,需要在pages.json中配置 "enablePullDownRefresh": true 才能生效。
    onPullDownRefresh() {
      console.log('用户下拉刷新时触发');
      // 执行刷新操作
      uni.stopPullDownRefresh(); // 停止下拉刷新动画
    }
    
  7. onReachBottom():

    • 监听用户上拉触底事件。
    onReachBottom() {
      console.log('用户上拉触底时触发');
    }
    
  8. onPageScroll(Object):

    • 监听页面滚动事件,返回页面滚动位置信息。
    onPageScroll(Object) {
      console.log('页面滚动时触发', Object);
    }
    

这些生命周期函数提供了在不同阶段执行代码的机会,可以根据业务需求在相应的生命周期函数中编写代码。

二、路由跳转方式

uni-app中,路由跳转可以使用uni.navigateTo等方法,这些方法与原生小程序的路由跳转方式相似。以下是一些常用的路由跳转方式:

  1. uni.navigateTo:

    • 用于跳转到应用内的非 tabBar 页面。
    uni.navigateTo({
      url: '/pages/detail/detail'
    });
    
  2. uni.redirectTo:

    • 用于关闭当前页面,跳转到应用内的某个页面。
    uni.redirectTo({
      url: '/pages/index/index'
    });
    
  3. uni.reLaunch:

    • 关闭所有页面,打开到应用内的某个页面。
    uni.reLaunch({
      url: '/pages/index/index'
    });
    
  4. uni.switchTab:

    • 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。
    uni.switchTab({
      url: '/pages/home/home'
    });
    
  5. uni.navigateBack:

    • 关闭当前页面,返回上一级页面或多级页面。
    uni.navigateBack({
      delta: 1
    });
    
  6. 组件:

    • uni-app中可以使用 <uni-navto> 组件来实现页面跳转效果。
    <uni-navto url="/pages/detail/detail">跳转到详情页</uni-navto>
    

需要注意的是,在使用这些方法时,页面路径通常以/pages开头,然后是具体的页面路径。需要根据实际项目结构调整路径。另外,uni-app的路由跳转方法会在不同平台(如H5、微信小程序、App等)进行适配,无需过多考虑平台差异。

三、页面组件通讯方式

  • uni-app中,页面通讯方式主要有以下几种:
  1. 页面传参:

    • 在页面跳转时,可以通过uni.navigateTouni.redirectTo等路由跳转方法的 url 参数传递数据。
    • 接收数据的页面通过onLoad生命周期函数中的 options 参数获取传递的数据。
    // 页面 A
    uni.navigateTo({
      url: '/pages/B/B?param1=value1&param2=value2'
    });
    
    // 页面 B
    onLoad(options) {
      console.log('接收参数:', options.param1, options.param2);
    }
    
  2. 全局变量或 Vuex 状态管理:

    • 使用全局变量或 Vuex(如果使用了 Vuex)来在不同页面之间共享数据。
    // 全局变量
    uni.$emit('eventName', data); // 发送数据
    uni.$on('eventName', (data) => {
      console.log('接收数据:', data);
    });
    
    // Vuex
    // 见 Vuex 文档,通过 mutations、actions 等修改和获取全局状态
    
  3. 本地存储:

    • 使用本地存储(localStorage、uni.setStorageSync/uni.getStorageSync)在页面间传递数据。
    // 页面 A
    uni.setStorageSync('key', 'value');
    
    // 页面 B
    let data = uni.getStorageSync('key');
    console.log('接收数据:', data);
    
  4. 事件总线:

    • 使用事件总线实现发布订阅模式,通过事件触发和监听来传递数据。
    // 事件总线
    const eventBus = new Vue();
    eventBus.$emit('eventName', data); // 发送数据
    
    // 页面 B
    eventBus.$on('eventName', (data) => {
      console.log('接收数据:', data);
    });
    
  5. uni-parent/uni-listen 组件通信:

    • uni-parentuni-listen 组件提供了简单的父子组件通信方式。
    <!-- 父组件 -->
    <uni-parent ref="parentRef"></uni-parent>
    
    <!-- 子组件 -->
    <uni-listen ref="listenRef"></uni-listen>
    
    // 在父组件中通过 ref 获取子组件实例并调用方法传递数据
    this.$refs.parentRef.methodName(data);
    
    // 在子组件中通过 ref 获取父组件实例并调用方法接收数据
    this.$refs.listenRef.methodName(data);
    

选择合适的通讯方式取决于具体的场景和需求。使用路由传参适用于简单的数据传递,而状态管理、本地存储、事件总线等方式则更适用于复杂的数据共享和组件通信。

四、使用组件

uni-appeasycom机制,将组件引用进一步优化,开发者只管使用,无需考虑导入和注册,更为高效:

<template>
	<view>
		<!-- 1.使用组件 -->
		<uni-rate text="1"></uni-rate>
	</view>
</template>
<script>
</script>

在 uni-app 项目中,页面引用组件和组件引用组件的方式都是一样的(可以理解为:页面是一种特殊的组件),均支持通过 easycom 方式直接引用。

五、用scroll-view实现下拉刷新

        <!-- 下拉刷新 -->
	<scroll-view 
		:scroll-y="true" 
		style="height: 100%;"
		:refresher-enabled="true"
		:refresher-triggered="triggered"
		:refresher-threshold="50" 
		refresher-background="lightgreen"
		@refresherpulling="onPulling"
		@refresherrefresh="onRefresh"
		@refresherrestore="onRestore"
		@refresherabort="onAbort"
		refresher-default-style="none"
	>
        	</scroll-view>
	<!-- 下拉刷新 -->
    
    const triggered = ref(false) // 设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发
    const _freshing  = ref(false) // 
    const pullText = ref('下拉即可刷新')
    
    // 3.下拉刷新
	//3.1-下拉刷新控件被下拉
	const onPulling = (e) => { // 自定义下拉刷新控件被下拉
		if (e.detail.deltaY > 50) {
			pullText.value = '松开即可刷新'
		}
	}
	//3.2-下拉刷新被触发
	const onRefresh = () => { // 自定义下拉刷新被触发
		console.log('onRefresh')
		if (_freshing.value) return // 表示在刷新状态,结束
		_freshing.value = true // 表示在刷新状态
		triggered.value = true;
		pullText.value = '正在刷新'
		// 刷新数据
		setTimeout(() => {
		getProListData().then(res => {
			proList.value = res.data.data
			triggered.value = false
			_freshing.value = false
			count.value = 2
		})
		}, 3000)
	}
	//3.3-下拉刷新被复位
	const onRestore = () => { // 自定义下拉刷新被复位
		// triggered.value = 'restore'; // 需要重置
		triggered.value = false
		_freshing.value = false
		pullText.value = '下拉即可刷新'
		console.log("onRestore");
	}
	//3.4-下拉刷新被中止	
	const onAbort = () => { // 自定义下拉刷新被中止	
		console.log("onAbort");
	}
	
	// 4.上拉加载
	onReachBottom(() => {
		getProListData({ count: count.value }).then(res => {
			if (res.data.data.length === 0) {
				uni.showToast({
					title: '没有更多数据了',
					icon: 'none'
				})
			} else {
				proList.value = [...proList.value, ...res.data.data]
				count.value += 1
			}
		})
	})

六、全选

      <!-- 3.1全选框 -->
							<checkbox-group @change="changeSelectOne(item)" style="line-height: 90px;">
								<checkbox :checked="item.flag"/>
							</checkbox-group>
                                                                <!-- 3.1全选框 -->
    
        	<!-- 3.5全选和提交订单 -->
			<view class="tip">
				<checkbox-group  @change="changeSelect">
					<checkbox :checked="checked" style="width:30px;line-height: 50px;"/>
				</checkbox-group>
				<view style="line-height: 50px;">
					商品总数:{{ totalNum }}--商品总价:{{totalPrice}}元
				</view>
				<button :disabled="totalNum === 0" style="margin-right:0;background-color: rgb(93 169 95 / 90%);color:#fff;font-weight: 600;border-radius: 18px;height:30px;line-height: 30px;margin-top:10px;font-size: 18px;">提交订单</button>
			</view>
                <!-- 3.5全选和提交订单 -->
    
    // 4.全选数据
const checked = ref(false)
    // 3.全选功能
    // 1.获取购物车数据功能
const getCartList = () => {
	getCartListData({ userid: uni.getStorageSync('userid')}).then(res => {
		if(res.data.code === '10020') {
			cartList.value = []
			empty.value = true
		} else {
			cartList.value = res.data.data
			empty.value = false
			checked.value = cartList.value.every(item => item.flag)
		}
	})
}
    // 3.1单个全选
const changeSelectOne = (item) => {
	item.flag = !item.flag
	// console.log(item.flag)
	selectOneData({
		cartid: item.cartid,
		flag: item.flag
	}).then(() => { getCartList() })
}
// 3.2总体全选
const changeSelect = (e) => {
	checked.value = !checked.value
	selectAllData({
		userid: uni.getStorageSync('userid'),
		type: checked.value
	}).then(() => { getCartList() })
}