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)

javascript 复制代码
<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 请求示例(提交数据)

javascript 复制代码
<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

javascript 复制代码
// utils/request.js
export const request = (options) => {
  // 显示加载中(若options.showLoading为false,则不显示)
  if (options.showLoading !== false) {
    uni.showLoading({ title: '加载中...' })
  }
  
  // 返回Promise,支持async/await
  return 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)

javascript 复制代码
<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()

示例:存储与获取用户信息

javascript 复制代码
<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)

javascript 复制代码
<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)

用于局部滚动(如横向滚动列表、纵向滚动长列表)

javascript 复制代码
<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(裁剪模式),适配不同场景

javascript 复制代码
<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>
相关推荐
Jeffrey__Lin3 小时前
解决ElementPlus使用ElMessageBox.confirm,出现层级低于el-table的问题
前端·javascript·elementui·vue·elementplus
咖啡の猫3 小时前
Vue-MVVM 模型
前端·javascript·vue.js
xvmingjiang3 小时前
Element Plus el-table 默认勾选行的方法
前端·javascript·vue.js
野生yumeko4 小时前
伪静态WordPress/Vue
前端·javascript·vue.js
爱因斯坦乐4 小时前
【vue】I18N国际化管理系统
前端·javascript·vue.js·笔记·前端框架
学好statistics和DS4 小时前
【CV】神经网络中哪些参数需要被学习?
人工智能·神经网络·学习
一只游鱼4 小时前
vue集成dplayer
前端·javascript·vue.js·播放器·dplayer
Rousson5 小时前
硬件学习笔记--82 连接器的选用原则与流程
笔记·单片机·学习
Larry_Yanan7 小时前
QML学习笔记(四十)QML的ApplicationWindow和StackView
c++·笔记·qt·学习·ui