uni-app--》基于小程序开发的电商平台项目实战(五)

news2025/1/13 17:26:47

🏍️作者简介:大家好,我是亦世凡华、渴望知识储备自己的一名在校大学生

🛵个人主页:亦世凡华、

🛺系列专栏:uni-app

🚲座右铭:人生亦可燃烧,亦可腐败,我愿燃烧,耗尽所有光芒。

👀引言

        ⚓经过web前端的学习,相信大家对于前端开发有了一定深入的了解,今天我开设了uni-app专栏,主要想从移动端开发方向进一步发展,而对于我来说写移动端博文的第二站就是uni-app开发,希望看到我文章的朋友能对你有所帮助。

今天开始使用 vue3 + uni-app 搭建一个电商购物的小程序,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的GitHub上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多关注本专栏,学习更多前端uni-app知识。然后开篇先简单介绍一下本项目用到的技术栈都有哪几个方面(阅读此次项目实践文章能够学习到的技术):

uni-app:跨平台的应用开发框架,基于vue.js可以一套代码同时构建运行在多个平台。

pnpm:高性能、轻量级npm替代品,帮助开发人员更加高效地处理应用程序的依赖关系。

vue3:vue.js最新版本的用于构建用户界面的渐进式JavaScript框架。

typescript:JavaScript的超集,提供了静态类型检查,使得代码更加健壮。

pinia:vue3构建的Vuex替代品,具有响应式能力,提供非常简单的 API,进行状态管理。

uni-ui:基于vue.js和uni-app的前端UI组件库,开发人员可以快速地构建跨平台应用程序。

如果是第一次接触uni-app并且想学习uni-app的朋友,我是不建议直接从此次实战项目开始看起,可以先阅读一下我以前的基础文章:什么是uniapp?如何开发uniapp?按部就班的学习可以让学习变得更轻松更容易上手哦,闲话少说我们直接开始今天的uni-app实战篇。

目录

个人中心模块搭建

设置页面的搭建

个人信息页搭建

个人信息页面数据的修改


个人中心模块搭建

在个人中心模块搭建时,这里我们打算使用自定义导航栏来设置个人模块的搭建,如果想使用自定义导航栏,我们需要在 pages.json 文件设置如下属性:

设置完自定义导航栏之后,导航栏的内容就会被组件的内容自动顶上去了,所以接下来我们就需要设置页面就可以了,在个人中心模块有两个页面需要展示,一个是登录成功的页面另一个是未登录的页面,两个页面下面都是有相应的猜你喜欢组件的相关内容,这里我们思考了一下,猜你喜欢组件的使用频率相对来说较高,所以我们把公共模块的组件代码封装成全局组件来进行公共的复用:

import { ref } from 'vue'
import type { SwGuessInstance } from '@/types/components'

/**
 * 猜你喜欢组合式函数
 */
export const useGuessList = () => {
  // 获取猜你喜欢组件实例
  const guessRef = ref<SwGuessInstance>()
  // 滚动触底事件
  const onScrolltolower = () => {
    guessRef.value?.getGuess()
  }
  // 返回 ref 和事件处理函数
  return {
    guessRef,
    onScrolltolower,
  }
}

个人中心模块展示不同页面的条件是根据仓库中用户信息是否存在展示的,这里需要直接调用该模块即可,通过v-if和v-else来进行相应的展示,给该滚动容器设置自定义上拉触底事件:

因为我们把自定义上拉触底事件封装成公共组件,这里直接调用即可:

const { guessRef, onScrolltolower } = useGuessList()

既然我们把猜你喜欢的公共代码模块封装成公共组件,在首页的相关猜你喜欢组件内容的模块代码也可以直接删掉换上公共代码的调用即可:

最终呈现的结果如下:

设置页面的搭建

关于设置页面一般用户不会主动去点击,这也就导致设置页面的停留次数相对较少,这里我们可以将设置页面设置一下分包,这里需要了解以下两个概念:

小程序分包:将小程序的代码分割成多个部分,分别打包成多个小程序包,减少小程序的加载时间,提高用户体验。

分包预下载:在进入小程序某个页面时,由框架自动预下载可能需要的分包,提升进入后续分包页面时的加载速度。

关于分包的其他相关概念这里不再赘述,想了解更深一点的朋友可以参考我之前的文章:分包

在 vscode 中我们新建分包页面,插件已经给我们提供好了方式,只需要在相应的文件夹下鼠标右键选择新建uniapp页面(分包)即可,如下:

为了避免和主页面pages文件夹搞混淆,这里我们可以在src文件夹下重新创建一个新的文件,然后在该文件夹下再重新创建分包文件:

当我们创建分包页面的时候,相应的的在pages.json文件夹下也会生成相应的分包加载规则:

接下来我们在个人中心的设置按钮处设置相应的跳转路径:

通过如下代码来搭建设置页面的基础样式:

<template>
  <view class="viewport">
    <!-- 列表1 -->
    <view class="list" v-if="true">
      <navigator url="/pagesMember/address/address" hover-class="none" class="item arrow">
        我的收货地址
      </navigator>
    </view>
    <!-- 列表2 -->
    <view class="list">
      <button hover-class="none" class="item arrow" open-type="openSetting">授权管理</button>
      <button hover-class="none" class="item arrow" open-type="feedback">问题反馈</button>
      <button hover-class="none" class="item arrow" open-type="contact">联系我们</button>
    </view>
    <!-- 列表3 -->
    <view class="list">
      <navigator hover-class="none" class="item arrow" url=" ">关于小程序</navigator>
    </view>
    <!-- 操作按钮 -->
    <view class="action">
      <view class="button">退出登录</view>
    </view>
  </view>
</template>

呈现的效果如下:

搭建完相关页面之后,接下来在 pages.json 文件夹下设置分包预下载规则,关于该小程序分包预下载的相关规则这里不再赘述,想了解的朋友可以直接查看官网,这里直接给出该规则:

// 分包预下载规则
"preloadRule": {
	"pages/my/my" :{
		"network": "all",
		"packages": ["subpackage"]
	}
}

分包规则设置完成之后,接下来我们就可以看到,当我们访问其他页面的时候页面是正常加载的,当我们访问个人中心页面的时候,分包会自动预下载方便我们进入的分包页面:

接下我们给退出登录设置点击事件,这里我们给其相应的点击事件设置模态框提示用户退出登录的相关确定,相关代码如下:

<script setup lang="ts">
import { useMemberStore } from '@/store'

const memberStore = useMemberStore()
// 退出登录
const onLogout = () => {
  // 模态弹窗
  uni.showModal({
    content: '是否退出登录',
    showCancel: true,
    success: (res) => {
      if (res.confirm) {
        // 清理用户信息
        memberStore.clearProfile()
        // 返回上一页
        uni.navigateBack()
      }
    },
  })
}
</script>

这里设置一下条件渲染,当用户未登录的情况下,需要将收获地址和相应的退出登录按钮进行相应的删除,代码如下:

最后呈现的结果如下:

个人信息页搭建

个人信息页是用户点击个人中心页面的用户头像或更改头像昵称跳转到个人信息页面,这里的个人信息页面也采用分包的方式,所以这里我们只需要在专门设置分包的文件夹下设置新文件profile来作为个人信息页的页面,创建页面之后在个人中心页面的相应位置设置跳转链接:

接下来编写相应的接口函数来获取个人信息数据:

// 封装个人信息数据接口
import type { ProfileDetail } from '@/types/member'
import { http } from '@/utils/http'

/**
 * 获取个人信息
 */
export const getMemberProfileAPI = () => {
  return http<ProfileDetail>({
    method: 'GET',
    url: '/member/profile',
  })
}

这里的ts类型可以将公共部分的参数分离出去,然后将独有的参数和公共的部分合并在一起:

/** 通用的用户信息 */
type BaseProfile = {
  /** 用户ID */
  id: number
  /** 头像  */
  avatar: string
  /** 账户名  */
  account: string
  /** 昵称 */
  nickname?: string
}

/** 小程序登录 登录用户信息 */
export type LoginResult = BaseProfile & {
  /** 手机号 */
  mobile: string
  /** 登录凭证 */
  token: string
}

/** 个人信息 用户详情信息 */
export type ProfileDetail = BaseProfile & {
  /** 性别 */
  gender?: Gender
  /** 生日 */
  birthday?: string
  /** 省市区 */
  fullLocation?: string
  /** 职业 */
  profession?: string
}

编写完相应的接口之后,接下来就需要进行引入该接口函数然后将返回的数据存储在ref数据中:

import { ref } from 'vue'
// 导入接口函数
import { getMemberProfileAPI } from '@/api/profile'
import { onLoad } from '@dcloudio/uni-app'
import type { ProfileDetail } from '@/types/member'

// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()
// 获取个人信息的接口
const profile = ref<ProfileDetail>()
const getMemberProfileData = async () => {
  const res = await getMemberProfileAPI()
  profile.value = res.result
}
// 页面加载时候调用
onLoad(() => {
  getMemberProfileData()
})

将ref数据通过插值表达式和v-bind数据绑定来动态的呈现数据,具体的页面结果如下:

个人信息页面数据的修改

修改用户头像:这里修改图片的方式我们需要借助uniapp相应的api,其相应的参数讲解这里不再赘述,想了解的可以参考相应的官方文档即可。其具体的代码如下:

// 修改头像
const onAvatarChange = () => {
  // 调用拍照/选择图片API
  uni.chooseMedia({
    count: 1, // 文件个数
    mediaType: ['image'], // 文件类型
    success: (res) => {
      console.log(res)
    },
  })
}

结果如下:

接下来借助uniapp中的上传文件的api进行相应的操作,完整的代码如下:

// 修改头像
const onAvatarChange = () => {
  // 调用拍照/选择图片API
  uni.chooseMedia({
    count: 1, // 文件个数
    mediaType: ['image'], // 文件类型
    success: (res) => {
      // 本地路劲
      const { tempFilePath } = res.tempFiles[0]
      // 文件上传
      uni.uploadFile({
        url: '/member/profile/avatar', // 接口地址
        name: 'file', // 接口参数
        filePath: tempFilePath, // 文件路径
        success: (res) => {
          if (res.statusCode === 200) {
            const avatar = JSON.parse(res.data).result.avatar
            // 个人信息页数据更新
            profile.value!.avatar = avatar
            // store头像更新
            memberStore.profile!.avatar = avatar
            uni.showToast({ icon: 'success', title: '更新成功' })
          } else {
            uni.showToast({ icon: 'error', title: '出现错误' })
          }
        },
      })
    },
  })
}

最后的结果如下:

接下来开始收集相应的表单数据进行数据的更新,首先这里我们先编写相应的接口函数,如下:

/**
 * 修改个人信息
 * @param data 请求体参数
 */
export const putMemberProfileAPI = (data: ProfileParams) => {
  return http<ProfileDetail>({
    method: 'PUT',
    url: '/member/profile',
    data,
  })
}

昵称方面的数据这里我们之间使用v-model双向数据绑定即可,使用非空断言避免其初始值不存在也就是undefined的情况,如下:

关于性别的单选框和生日方面的内容,这里直接在相应的表单中设置change函数监听其变化:

将动态改变的值存放在响应式ref数据当中:

// 修改性别
const onGenderChange: UniHelper.RadioGroupOnChange = (ev) => {
  profile.value.gender = ev.detail.value as Gender
}
// 修改生日
const onBirthdayChange: UniHelper.DatePickerOnChange = (ev) => {
  profile.value.birthday = ev.detail.value
}

选择城市方面这里也是采用相应的change事件监听其变化:

修改城市的方面需要提供两个数据,一个是前端需要的数据另一个是后端需要的数据:

// 修改城市
let fullLocationCode: [string, string, string] = ['', '', '']
const onFullLocationChange: UniHelper.RegionPickerOnChange = (ev) => {
  // 这是前端页面需要的详细文字数据
  profile.value.fullLocation = ev.detail.value.join(' ')
  // 这是后端需要地区编码的数据
  fullLocationCode = ev.detail.code!
}

最后给保存按钮设置点击函数,该函数里面调用相应的修改个人信息的接口函数,将我们收集的表单数据作为参数传递给接口函数当中:

// 点击按钮保存表单
const onSubmit = async () => {
  // 结构相应的数据
  const { nickname, gender, birthday } = profile.value
  const res = await putMemberProfileAPI({
    nickname,
    gender,
    birthday,
    provinceCode: fullLocationCode[0],
    cityCode: fullLocationCode[1],
    countyCode: fullLocationCode[2],
  })
  // 更新store昵称
  memberStore.profile!.nickname = res.result.nickname
  uni.showToast({ icon: 'success', title: '保存成功' })
  setTimeout(() => {
    uni.navigateBack()
  }, 400)
}

最终呈现的结果如下:

本项目个人中心页面、个人信息页面的一些基本功能的搭建就讲解到这,下一篇文章将继续讲解项目其他页面操作,关注博主学习更多前端uni-app知识,您的支持就是博主创作的最大动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1090336.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring实战 | Spring AOP核心功能分析之葵花宝典

国庆中秋特辑系列文章&#xff1a; 国庆中秋特辑&#xff08;八&#xff09;Spring Boot项目如何使用JPA 国庆中秋特辑&#xff08;七&#xff09;Java软件工程师常见20道编程面试题 国庆中秋特辑&#xff08;六&#xff09;大学生常见30道宝藏编程面试题 国庆中秋特辑&…

实验3:左右循环LED灯

获取流水灯工程&#xff1a; 方式一&#xff1a; keilproteus 完成最小系统&#xff0c;点亮led 灯实验_吴小凹的博客-CSDN博客 方式二&#xff1a; Flowing_led.zip - 蓝奏云直接下载。 原理图修改&#xff1a; 无须修改只需要使用流水灯的工程即可&#xff0c;解压到桌面…

机器人命令表设计

演算命令 CLEAR 将数据 1 上被指定的编号以后的变数的内容&#xff0c;以及数据 2 上仅被指定的个数都清除至 0。 INC 在被指定的变数内容上加上 1。 DEC 在被指定的变数内容上减掉 1。 SET 在数据 1 上设定数据 2。 ADD 将数据 1 和数据 2 相加&#xff0c;得出的结果保存在数…

小华HC32F448串口使用

目录 1. 串口GPIO配置 2. 串口波特率配置 3. 串口接收超时配置 4. 串口中断注册 5. 串口初始化 6. 串口数据接收处理 7. DMA接收配置和处理 1. 串口GPIO配置 端口号和Pin脚号跟STM32没什么区别。 串口复用功能跟STM32大不一样。 如下图&#xff0c;选自HC32F448 表 2…

AI 律助 Alpha GPT 线上实操发布会,重磅发布!

数字化时代,随着人工智能的迅猛发展,各行各业都在积极探索通过智能化工具实现工作效率翻升的可能性。“ ChatGPT 类产品”是未来办公应用软件发展的重要趋势之一,但如何将 ChatGPT 真正应用于法律人的工作,赋能效率提升?法律行业同样面临着新的挑战和机遇。 破局的关键是实现技…

mysql面试题50:500台数据库,如何在最快时间之内重启

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:500台db,如何在最快时间之内重启呢? 如果需要在最快时间内重启500台数据库,可以考虑采用并行化和自动化的方法来提高效率。比如: 编写自动化脚…

ubuntu中查看进程并结束进程以查看资源占用命令

ps命令&#xff1a;可以列出正在运行的进程。ps -e ps -aux 查看所有进程&#xff0c;每行一个程序&#xff08;常用&#xff09;ps -A 查看当前系统所有的进程。&#xff08;常用&#xff09;ps -A | grep chrome 命令去搜索某个指定进程。&#xff08;常用&#xff09;ps -A…

SQL sever中的索引

目录 一、索引定义 二、索引结构 2.1. B-树索引结构&#xff1a; 2.2. 哈希索引结构&#xff1a; 三、索引作用 四、索引与约束区别 五、索引级别 六、索引分类 6.1. 聚集索引&#xff08;Clustered Index&#xff09;&#xff1a; 6.2. 非聚集索引&#xff08;Noncl…

2023年中国石油测井设备市场格局及存在问题分析[图]

油气勘探就是利用各种勘探手段寻找和查明油气资源、确定油气聚集有利地区、找到储油气的圈闭、探明油气田面积和油气层情况并预测产出能力的过程&#xff1b;油气开发是在油田最终投产前的必要环节。 随着石油测井行业的不断发展&#xff0c;使用测井仪器的测井服务单位对仪器无…

华为云云耀云服务器L实例评测|华为云耀云服务器L实例docker部署及应用(七)

八、华为云耀云服务器L实例docker、docker-compose安装及部署MySQL、Redis应用&#xff1a; 随着云原生、容器化、微服务、K8S等技术的发展&#xff0c;容器 docker 也逐渐在企业团队实践中大量的使用。它可以提供了一套标准化的解决方案&#xff0c;极大地提升了部署、发布、运…

生成Android证书

前提&#xff1a;确保本机安装好了java1.8 第一步 打开CMD keytool -genkey -alias AAAA -keyalg RSA -keysize 2048 -validity 36500 -keystore D:\mygitee\keyStore\szxApp.jksD:\mygitee\keyStore\szxApp.jks是证书要生成的位置 szxApp.jks 是证书名称 D:\mygitee\keySto…

八大排序算法(含时间复杂度、空间复杂度、算法稳定性)

文章目录 八大排序算法(含时间复杂度、空间复杂度、算法稳定性)1、&#xff08;直接&#xff09;插入排序1.1、算法思想1.2、排序过程图解1.3、排序代码 2、希尔排序3、冒泡排序3.1、算法思想3.2、排序过程图解3.3、排序代码 4、&#xff08;简单&#xff09;选择排序4.1、算法…

Web应用防火墙的性能优化技术

Web应用防火墙&#xff08;WAF&#xff09;是企业网络安全的重要屏障&#xff0c;其性能直接影响到网络服务的质量和安全。本文详细探讨了WAF性能优化的几种技术&#xff0c;旨在为网络安全专业人员提供实用的参考。 规则优化 1.1 精简规则集 规则评估&#xff1a;定期评估规…

深入了解Spring Boot Actuator

文章目录 引言什么是ActuatorActuator的底层技术和原理端点自动配置端点请求处理端点数据提供端点数据暴露 如何使用Actuator添加依赖访问端点自定义端点 实例演示结论 引言 Spring Boot Actuator是一个非常强大且广泛使用的模块&#xff0c;它为Spring Boot应用程序提供了一套…

数据库:Hive转Presto(五)

此篇将所有代码都补充完了&#xff0c;之前发现有的代码写错了&#xff0c;以这篇为准&#xff0c;以下为完整代码&#xff0c;如果发现我有什么考虑不周的地方&#xff0c;可以评论提建议&#xff0c;感谢。代码是想哪写哪&#xff0c;可能比较繁琐&#xff0c;还需要优化。 …

Kafka SASL认证授权(五)ACL源码解析

Kafka SASL认证授权(五)ACL源码解析。 官网地址:https://kafka.apache.org/ 一、ACL检查流程解析 一起看一下kafka server的启动与监听流程: Kafka -> KafkaServer -> SocketServer、KafkaRequestHandler 其中KafkaServer做相关的初始化,包括SocketServer 与 han…

实体解析实施的复杂性

实体的艺术表现斯特凡伯克纳 一、说明 实体解析是确定数据集中的两条或多条记录是否引用同一现实世界实体&#xff08;通常是个人或公司&#xff09;的过程。乍一看&#xff0c;实体分辨率可能看起来像一个相对简单的任务&#xff1a;例如&#xff0c;给定一张人物的两张照片&a…

AOMEI PXE Boot Free

两台电脑网线直连&#xff0c;不用设置固定IP&#xff0c;该软件包含DHCP。 名称: 3H3AOMEIPXEBootFree.rar 大小: 13068734 字节 (12 MiB) SHA1: 1e606c8c1ee3badf8af9a87f61fdf2e332b773e6 名称: PXEBoot.exe 大小: 13124928 字节 (12 MiB) SHA1: 95286ac18e9b81c2a68412c40…

尿检设备“智能之眼”:维视智造推出MV-MC 系列医疗专用相机

​ 尿液分析是临床检验的基础常规项目&#xff0c;随着医疗设备的不断发展&#xff0c;尿液分析相关仪器的国产化和自动化程度也进一步提升。2022 年国内尿液分析市场的规模约为 28 亿元&#xff0c;激烈的竞争推动了尿检仪器自动化、智能化升级&#xff0c;在仪器中加入机器视…

布朗大学发现GPT-4存在新问题,可通过非常见语言绕过限制

&#x1f989; AI新闻 &#x1f680; 布朗大学发现GPT-4存在新漏洞&#xff0c;可通过非常见语言绕过限制 摘要&#xff1a;布朗大学计算机科学研究人员发现了OpenAI的GPT-4存在新漏洞&#xff0c;利用不太常见的语言如祖鲁语和盖尔语可以绕过各种限制。研究人员测试了GPT-4对…