uniapp学习【路由跳转 +数据请求+本地存储+常用组件】
Uniapp 封装了小程序的原生 API 和组件,提供更统一的调用方式
1 路由跳转(页面切换)
Uniapp 提供多种路由跳转方式,区别如下(核心是pages.json
中配置的页面路径)
跳转 API | 作用 | 适用场景 | 注意事项 |
---|---|---|---|
uni.navigateTo | 保留当前页面,跳转到新页面(可返回) | 首页→详情页、列表页→详情页 | 页面栈最多 10 层,不能跳转到 tab 页面 |
uni.switchTab | 关闭所有非 tab 页面,跳转到 tab 页面 | 非 tab 页面→tab 页面(如详情页→首页) | 只能跳转到tabBar 配置的页面 |
uni.redirectTo | 关闭当前页面,跳转到新页面(不可返回) | 登录页→首页、引导页→首页 | 不能跳转到 tab 页面 |
uni.reLaunch | 关闭所有页面,跳转到新页面 | 退出登录后→登录页 | 可跳转到任意页面 |
uni.navigateBack | 返回上一页面(或指定层数) | 详情页→列表页、子页面→父页面 | 需要配合uni.navigateTo 使用 |
示例:路由跳转与传
1.跳转并传参(首页→详情页)
<!-- 首页(pages/index/index.vue) -->
<template><view><button @click="goToDetail">跳转到详情页</button></view>
</template><script setup>
const goToDetail = () => {// 跳转到详情页,并传递参数(id=1,name=Uniapp)uni.navigateTo({url: '/pages/detail/detail?id=1&name=Uniapp'})
}
</script>
2.接收参数(详情页)
<!-- 详情页(pages/detail/detail.vue) -->
<script setup>
import { onLoad } from '@dcloudio/uni-app'// 在onLoad中接收路由参数(options是传递的参数对象)
onLoad((options) => {console.log('接收的参数:', options) // 输出:{ id: '1', name: 'Uniapp' }const id = options.id // 注意:参数值都是字符串类型,需手动转数字const name = options.name
})
</script>
3.返回上一页面(详情页→首页):
<!-- 详情页 -->
<template><button @click="goBack">返回首页</button>
</template><script setup>
const goBack = () => {// 返回上一页面(delta=1表示返回1层,默认1)uni.navigateBack({delta: 1})
}
</script>
2 数据请求(调用接口)
Uniapp 用uni.request
封装了小程序的原生请求,支持 GET/POST 等方法
2.1. 基础请求示例(GET)
<script setup>
import { ref, onLoad } from 'vue'
const list = ref([]) // 存储请求到的数据onLoad(() => {// 页面加载时发起请求getListData()
})// 封装请求函数
const getListData = () => {// 显示加载中提示uni.showLoading({ title: '加载中...' })uni.request({url: 'https://api.example.com/list', // 接口地址(需替换为真实接口)method: 'GET', // 请求方法(默认GET,可省略)data: { // 请求参数(GET请求会拼接到URL后)page: 1,size: 10},header: { // 请求头(如需要Token认证)'Content-Type': 'application/json','Token': 'your-token' // 若接口需要登录认证,需传递Token},success: (res) => {// 请求成功(res.data是接口返回的数据)console.log('请求成功:', res.data)if (res.data.code === 200) { // 假设接口返回code=200表示成功list.value = res.data.data // 将数据赋值给响应式变量} else {uni.showToast({ title: res.data.msg, icon: 'none' }) // 显示错误提示}},fail: (err) => {// 请求失败(如网络错误、接口不存在)console.error('请求失败:', err)uni.showToast({ title: '网络错误,请重试', icon: 'none' })},complete: () => {// 请求完成(无论成功/失败都会执行)uni.hideLoading() // 隐藏加载中提示}})
}
</script>
2.2 POST 请求示例(提交数据)
<script setup>
const submitData = () => {uni.showLoading({ title: '提交中...' })uni.request({url: 'https://api.example.com/submit',method: 'POST',data: { // POST请求参数(会放在请求体中)name: '小白',age: 18},header: {'Content-Type': 'application/json' // POST请求需指定Content-Type},success: (res) => {if (res.data.code === 200) {uni.showToast({ title: '提交成功' })}},fail: (err) => {uni.showToast({ title: '提交失败', icon: 'none' })},complete: () => {uni.hideLoading()}})
}
</script>
2.3 封装请求(避免重复代码)
为了避免每个页面都写uni.request
,可在utils
文件夹下封装一个请求工具(request.js
)
// utils/request.js
export const request = (options) => {// 显示加载中(若options.showLoading为false,则不显示)if (options.showLoading !== false) {uni.showLoading({ title: '加载中...' })}// 返回Promise,支持async/awaitreturn new Promise((resolve, reject) => {uni.request({// 基础URL(可统一配置,避免每个请求写完整URL)url: 'https://api.example.com' + options.url,method: options.method || 'GET',data: options.data || {},header: {'Content-Type': 'application/json','Token': uni.getStorageSync('token') // 从本地存储获取Token(登录后存储)},success: (res) => {// 统一处理响应(如Token过期跳转登录页)if (res.data.code === 401) { // 假设401表示Token过期uni.redirectTo({ url: '/pages/login/login' })return}resolve(res.data) // 将接口返回数据传给resolve},fail: (err) => {uni.showToast({ title: '网络错误,请重试', icon: 'none' })reject(err) // 将错误传给reject},complete: () => {if (options.showLoading !== false) {uni.hideLoading()}}})})
}
2.4 使用封装的请求(async/await)
<script setup>
import { ref, onLoad } from 'vue'
import { request } from '@/utils/request.js' // 引入封装的请求const list = ref([])onLoad(async () => {// 用async/await调用请求(更简洁)try {const res = await request({url: '/list', // 基础URL已在request.js中配置,这里只需写路径data: { page: 1, size: 10 },showLoading: true // 显示加载中(默认true,可省略)})if (res.code === 200) {list.value = res.data}} catch (err) {console.error('请求失败:', err)}
})
</script>
3 本地存储(保存数据到手机)
Uniapp 用uni.setStorageSync
/uni.getStorageSync
封装了小程序的本地存储,用于保存用户信息、Token 等数据(类似浏览器的localStorage
)
API | 作用 | 示例 |
---|---|---|
uni.setStorageSync | 同步存储数据(简单场景推荐) | uni.setStorageSync('token', 'abc123') |
uni.getStorageSync | 同步获取数据 | const token = uni.getStorageSync('token') |
uni.removeStorageSync | 同步删除数据 | uni.removeStorageSync('token') |
uni.clearStorageSync | 同步清空所有存储数据 | uni.clearStorageSync() |
示例:存储与获取用户信息
<script setup>
import { ref } from 'vue'// 存储用户信息(如登录后)
const saveUserInfo = () => {const userInfo = {name: '小白',age: 18,token: 'abc123456'}// 存储数据(key为'userInfo',value为JSON字符串,因为存储只支持字符串)uni.setStorageSync('userInfo', JSON.stringify(userInfo))uni.showToast({ title: '用户信息已保存' })
}// 获取用户信息(如页面加载时)
const getUserInfo = () => {// 获取数据(需解析JSON字符串)const userInfoStr = uni.getStorageSync('userInfo')if (userInfoStr) {const userInfo = JSON.parse(userInfoStr)console.log('用户信息:', userInfo)return userInfo} else {uni.showToast({ title: '未找到用户信息', icon: 'none' })return null}
}// 删除用户信息(如退出登录时)
const removeUserInfo = () => {uni.removeStorageSync('userInfo')uni.showToast({ title: '用户信息已删除' })
}
</script>
4 常用组件(Uniapp 自带)
4.1. 轮播图(swiper + swiper-item)
<template><view style="padding: 20rpx;"><swiper indicator-dots <!-- 显示指示器(小圆点) -->autoplay <!-- 自动轮播 -->interval="3000" <!-- 轮播间隔(毫秒) -->duration="500" <!-- 切换时长(毫秒) -->style="height: 300rpx;"><swiper-item><image src="/static/banner1.png" mode="widthFix" style="width: 100%;" /></swiper-item><swiper-item><image src="/static/banner2.png" mode="widthFix" style="width: 100%;" /></swiper-item></swiper></view>
</template>
4.2. 滚动视图(scroll-view)
用于局部滚动(如横向滚动列表、纵向滚动长列表)
<template><view style="padding: 20rpx;"><!-- 横向滚动 --><scroll-view scroll-x <!-- 允许横向滚动 -->white-space="nowrap" <!-- 禁止换行 -->style="height: 150rpx;"><view v-for="(item, index) in list" :key="index" style="display: inline-block; width: 200rpx; height: 150rpx; background: #f5f5f5; margin-right: 20rpx; text-align: center; line-height: 150rpx;">{{ item }}</view></scroll-view><!-- 纵向滚动(需指定高度) --><scroll-view scroll-y <!-- 允许纵向滚动 -->style="height: 300rpx; margin-top: 20rpx; background: #f5f5f5;"><view v-for="(item, index) in 20" :key="index" style="padding: 20rpx; border-bottom: 1rpx solid #eee;">纵向列表项 {{ item }}</view></scroll-view></view>
</template><script setup>
import { reactive } from 'vue'
const list = reactive(['item1', 'item2', 'item3', 'item4', 'item5'])
</script>
4.3图片(image)
Uniapp 的image
组件支持多种mode
(裁剪模式),适配不同场景
<template><view style="padding: 20rpx;"><!-- mode="widthFix":宽度固定,高度自适应(常用) --><image src="/static/avatar.png" mode="widthFix" style="width: 200rpx; margin-bottom: 20rpx;"/><!-- mode="aspectFill":填充容器,可能裁剪(常用) --><image src="/static/cover.png" mode="aspectFill" style="width: 100%; height: 200rpx; background: #eee;"/></view>
</template>