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

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

🛵个人主页:亦世凡华、

🛺系列专栏: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 = () => {// 调用拍照/选择图片APIuni.chooseMedia({count: 1, // 文件个数mediaType: ['image'], // 文件类型success: (res) => {console.log(res)},})
}

结果如下:

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

// 修改头像
const onAvatarChange = () => {// 调用拍照/选择图片APIuni.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 = avataruni.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.valueconst res = await putMemberProfileAPI({nickname,gender,birthday,provinceCode: fullLocationCode[0],cityCode: fullLocationCode[1],countyCode: fullLocationCode[2],})// 更新store昵称memberStore.profile!.nickname = res.result.nicknameuni.showToast({ icon: 'success', title: '保存成功' })setTimeout(() => {uni.navigateBack()}, 400)
}

最终呈现的结果如下:

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言进阶】自定义类型:结构体,枚举,联合

自定义类型&#xff1a;结构体&#xff0c;枚举&#xff0c;联合 1.结构体1.1结构体类的基础知识1.2结构的声明1.3特殊的声明1.4结构的自引用1.5结构体变量的定义和初始化1.6结构体内存对齐1.7修改默认对齐1.8结构体传参 2.段位2.1什么是段位2.2段位的内存分配2.3位段的跨平台问…

【Spring Boot】RabbitMQ消息队列 — RabbitMQ入门

💠一名热衷于分享知识的程序员 💠乐于在CSDN上与广大开发者交流学习。 💠希望通过每一次学习,让更多读者了解我 💠也希望能结识更多志同道合的朋友。 💠将继续努力,不断提升自己的专业技能,创造更多价值。🌿欢迎来到@"衍生星球"的CSDN博文🌿 🍁本…

Chrome使用本地修改过的js替换原js内容

步骤 1.进入开发人员工具&#xff1a;按F12 或 按ctrlshitfi 或 菜单“更多工具”->“开发人员工具” 2.在“源代码/来源”页面找到需要更改的js文件&#xff0c;“右键”->“替换内容” 3.在弹出的标签点击“选择文件夹”来选择一个存放内容的本地文件夹 4.弹出的询问标…

Excel——对其他工作表和工作簿的引用

一、引用其他sheet页表区域 若希望在公式中引用其他工作表的单元格区域&#xff0c;可以在公式编辑状态下&#xff0c;通过鼠标单击相应的工作表标签&#xff0c;然后选择相应的单元格区域。 例1 跨sheet页引用其他工作表区域 如图1所示的工作表Sheet2为工资表。 在Sheet1表…

【Golang】grpc环境踩的坑

关于’protoc-gen-go’ 不是内部或外部命令 这个问题的出现是因为没有这个文件导致的 这个文件要通过我们下载的google.golang.org这个文件编译生成的 这里建议下载google提供的grpc包 protobuf的源码&#xff1a; git clone https://github.com/golang/protobuf 下载好之后进…

如何把视频压缩变小?

如何把视频压缩变小&#xff1f;大家都知道&#xff0c;视频一般都伴随着很大的文件体积&#xff0c;&#xff1a;尤其是现在的视频大多是高清晰度的&#xff0c;因此视频文件的体积就更加的大&#xff0c;视频体积太大会给我们带来很多的不便&#xff0c;主要是以下这几点&…

诚迈科技董事长王继平出席中国(太原)人工智能大会并发表演讲

10月14日—15日&#xff0c;2023中国&#xff08;太原&#xff09;人工智能大会在山西省太原市举办。诚迈科技在大会上全面展示了其在人工智能领域的一系列创新技术与解决方案&#xff0c;诚迈科技董事长、统信软件董事长王继平受邀出席产业数字化转型论坛并发表主题演讲&#…

【特纳斯电子】基于单片机的火灾监测报警系统-实物设计

视频及资料链接&#xff1a;基于单片机的火灾监测报警系统-实物设计 - 电子校园网 (mcude.com) 编号&#xff1a; T0152203M-SW 设计简介&#xff1a; 本设计是基于单片机的火灾监测报警系统&#xff0c;主要实现以下功能&#xff1a; 1.通过OLED显示温度、烟雾、是否有火…

docker拉取镜像错误missing signature key

参考地址&#xff1a;docker拉取镜像错误 missing signature key-CSDN博客 linux系统&#xff0c;使用docker拉取的时候&#xff0c;报错如下 missing signature key 就一阵莫名其妙&#xff0c;之前还好好的&#xff0c;突然就不行了 按照网上说的方法&#xff0c;查看doc…

Ant Design Vue设置表格滚动 宽度自适应 不换行

Ant Design Vue设置表格滚动 宽度自适应 不换行 添加以下属性即可解决这个问题&#xff1a; <a-table :columns"columns" :data-source"list":pagination"false"bordered:scroll"{ x: max-content }" >

【QT开发(8)】QT 中使用tensorrt

在之前的文章《【TensorRT&#xff08;2&#xff09;】研究美团tech的yolov6的TensorRT部署》说明了tensorRT 的使用流程。今天尝试将其并入QT 项目中。 文章目录 项目地址参考资料&#xff1a;该分支主要做的工作Task 1:读取视频文件&#xff0c;然后通过 dds 发送的事情Task…

银河麒麟你服务x86访问ftp服务器上的文件

打开我的电脑 地址栏输入 ftp地址 可以选择需要的文件复制出来了

pytorch 入门(二)

本文为&#x1f517;小白入门Pytorch内部限免文章 &#x1f368; 本文为&#x1f517;小白入门Pytorch中的学习记录博客&#x1f366; 参考文章&#xff1a;【小白入门Pytorch】教案二&#x1f356; 原作者&#xff1a;K同学啊 目录 一、神经网络的组成部分1. 神经元2. 神经网络…

PyQt界面里如何加载本地视频以及调用摄像头实时检测(小白入门必看)

目录 1.PyQt介绍 2.代码实现 2.1实时调用摄像头 2.2 使用YOLOv5推理 2.3 代码中用到的主要函数 1.PyQt介绍 PyQt是一个用于创建桌面应用程序的Python绑定库&#xff0c;它基于Qt框架。Qt是一个跨平台的C应用程序开发框架&#xff0c;提供了丰富的图形界面、网络通信、数据…

阶段性总结

uart协议&#xff1a; 通用异步收发器 UART&#xff08;Universal Asynchronous Receiver/Transmitter)&#xff0c;是一种串行、异步、全双工的通信协议&#xff0c;将所需传输的数据一位接一位地传输&#xff0c;在UART通讯协议中信号线上的状态位高电平代表’1’&#xff0…

竞品价格怎么监测

品牌在做产品营销、产品定价时&#xff0c;除了要做好自身产品的研发设计外&#xff0c;需要非常了解市场&#xff0c;了解消费者偏好、了解竞品数据&#xff0c;通过对比分析&#xff0c;从而知道哪些价位的产品更受消费者喜爱&#xff0c;怎样设计产品更符合市场要求等&#…

黑马JVM总结(三十六)

&#xff08;1&#xff09;CAS-概述 cas是配合volatile使用的技术 &#xff0c;对共享变量的安全性要使用synachonized加锁&#xff0c;但是CAS不加锁&#xff0c;它是使用where&#xff08;true&#xff09;的死循环&#xff0c;里面compareAndSwap尝试把结果赋值给共享变量&…

linux下的rsync(文件同步) 用法教程

一、简介 rsync 是一个常用的 Linux 应用程序&#xff0c;用于文件同步。 它可以在本地计算机与远程计算机之间&#xff0c;或者两个本地目录之间同步文件&#xff08;但不支持两台远程计算机之间的同步&#xff09;。它也可以当作文件复制工具&#xff0c;替代cp和mv命令。 …

RAII与智能指针

RAII与智能指针 1.RAII1.1RAII理解1.2RAII的原理1.2.1简单的例子说明局部对象的自动销毁的特性 1.2.2 RAII 过程 2.智能指针2.1 auto_ptr2.1.1auto_ptr的使用构造函数与析构函数拷贝构造函数与赋值提领操作auto ptr其它函数 2.1.2autoptr使用的注意事项 2.2 unique_ptr2.2.1uni…

ros学习笔记(1)Mac本地安装虚拟机,安装Ros2环境

Ros与Linux的关系 Ros环境基于Linux系统内核 我们平时用的是Linux发行版&#xff0c;centos&#xff0c;ubuntu等等&#xff0c;机器人就用了ubunut 有时候我们经常会听到ubunue的版本&#xff0c;众多版本中&#xff0c;有一些是长期维护版TLS&#xff0c;有一些是短期维护…