当前位置: 首页 > news >正文

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知识,您的支持就是博主创作的最大动力!

相关文章:

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

&#x1f3cd;️作者简介&#xff1a;大家好&#xff0c;我是亦世凡华、渴望知识储备自己的一名在校大学生 &#x1f6f5;个人主页&#xff1a;亦世凡华、 &#x1f6fa;系列专栏&#xff1a;uni-app &#x1f6b2;座右铭&#xff1a;人生亦可燃烧&#xff0c;亦可腐败&#xf…...

新型的终端复用器 tmux

以前遇到长时间执行任务时&#xff0c;一般是使用nohup加后台运行&#xff0c;但是涉及到少量代码编写。 同事介绍了一个screen命令&#xff0c;根据文档&#xff0c;此命令已经过时&#xff0c;最新的命令是tmux。 tmux的介绍文档&#xff0c;RedHat的这一篇非常不错。 在文…...

标准化后端向前端传来的Json数据

后端响应固定格式给前端&#xff1a; 1&#xff0c;创建一个专门存储数据的类&#xff1b;分别存储响应状态码code&#xff0c;响应数据&#xff0c;传输的消息。 public class CommonData {int code;Object data;String message;public CommonData(int code, String message…...

java 两个list比较,删除相同的元素

概述 在Java开发中&#xff0c;经常需要比较两个List并删除相同的元素。本文将介绍整个流程&#xff0c;并提供相应的代码示例&#xff0c;帮助新手开发者完成这个任务。 流程 下面是比较两个List并删除相同元素的流程&#xff1a; 代码示例 创建两个List 我们首先需要创建两…...

7-3 zust-sy4-10 回文诗

7-3 zust-sy4-10 回文诗 分数 10 作者 张银南 单位 浙江科技学院 回文诗是汉语特有的一种使用词序回环往复的修辞方法&#xff0c;正着读反着读都可以。明末浙江才女吴绛雪作《四时山水诗》,如夏景诗&#xff1a;香莲碧水动风凉&#xff0c;水动风凉夏日长。长日夏凉风动水&…...

【数据结构】排序--插入排序(希尔排序)

目录 一 基本思想 二 直接插入排序 三 希尔排序 一 基本思想 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为 止&#xff0c;得到一个新的有序序列 。 实际中我们玩扑克牌时&#xff0c;就用了插入排序的思想 二…...

“探寻服务器的无限潜能:从创意项目到在线社区,你会做什么?”

文章目录 每日一句正能量前言什么是服务器&#xff1f;服务器能做什么&#xff1f;服务器怎么用&#xff1f;部署创意项目&#xff0c;还是在线社区亦或做其他的&#xff1f;后记 每日一句正能量 未知的下一秒&#xff0c;千万不要轻言放弃。 前言 在数字化时代&#xff0c;服…...

5年经验之谈 —— 深入了解性能测试:方法、工具和最佳实践!

性能测试是软件开发生命周期中至关重要的一部分&#xff0c;它有助于确保应用程序在不同负载条件下都能够高效运行。在竞争激烈的市场中&#xff0c;性能问题可能导致用户流失&#xff0c;损害声誉&#xff0c;并损害业务。本文将深入探讨性能测试的方法、工具和最佳实践&#…...

动态加载sprite是multiple模式(即该sprite包含了很多小图)里的小图

在Unity中&#xff0c;Resources.Load()方法可以用来加载资源。如果要加载Sprite下的multiple模式的图片&#xff0c;你需要知道这些图片的路径。 首先&#xff0c;你需要把你想要加载的资源放在一个名为"Resources"的文件夹内。然后&#xff0c;你可以使用以下代码…...

大数据 DataX 详细安装教程

目录 一、环境准备 二、安装部署 2.1 二进制安装 2.2 python 3 支持 三、Data X 初体验 3.1 配置示例 3.1.1. 生成配置模板 3.1.2 创建配置文件 3.1.3 运行 DataX 3.1.4 结果显示 3.2 动态传参 3.2.1. 动态传参的介绍 3.2.2. 动态传参的案例 3.3 迸发设置 …...

微信小程序开发之会议oa(首页搭建)

前言&#xff1a; 上一篇我们掌握了关于小程序的框架&#xff0c;这篇博客带你完成小程序版的会议OA首页。效果如下&#xff1a; 一&#xff0c; 1.1先创建OA首页页面&#xff1a; 首先我们先建一个新项目&#xff0c;在app.json中编写代码 {"pages": ["pages/…...

了解主启动类怎么运行

//SpringBootApplication 标注这个类是spring boot的应用&#xff0c;启动类下的所有资源都会被导入 SpringBootApplication public class SpringbootApplication { public static void main(String[] args) { //以为是启动了一个方法&#xff0c;没想到启动了一个服务 SpringA…...

【LeetCode】31. 下一个排列

1 问题 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地&a…...

支持语音与视频即时通讯项目杂记(一)

第一部分解释服务端的实现。 &#xff08;服务端结构&#xff09; 下面一个用于实现TCP服务器的代码&#xff0c;包括消息服务器&#xff08;TcpMsgServer&#xff09;和文件中转服务器&#xff08;TcpFileServer&#xff09;。 首先&#xff0c;TcpServer是TcpMsgServer和Tcp…...

文档:htm格式转txt

꧂ 两个地方都保存꧁ import os import codecs from bs4 import BeautifulSoupdef generate_output_filename(file_path, save_path):# 获取文件名&#xff08;不包含扩展名&#xff09;file_name os.path.splitext(os.path.basename(file_path))[0]# 构造保存路径和文件名ou…...

电子邮件地址注册过程详解

许多人可能对如何注册电子邮件地址感到困惑&#xff0c;本文将详细解析电子邮件地址的注册过程&#xff1a;确定邮箱厂商、创建邮箱账户、设置电子邮件地址。 1、确定要注册的邮箱厂商 首先我们需要确定要注册哪种类型的电子邮件服务。目前市场上有许多不同的电子邮件服务提供商…...

深度学习——卷积神经网络(CNN)基础二

深度学习——卷积神经网络&#xff08;CNN&#xff09;基础二 文章目录 前言三、填充和步幅3.1. 填充3.2. 步幅3.3. 小结 四、多输入多输出通道4.1. 多输入通道4.2. 多输出通道4.3. 11卷积层4.4. 小结 总结 前言 上文对卷积有了初步的认识&#xff0c;其实卷积操作就是通过卷积…...

R语言进度条:txtProgressBar功能使用方法

R语言进度条使用攻略 在数据处理、建模或其他计算密集型任务中&#xff0c;我们常常会执行一些可能需要很长时间的操作。 在这些情况下&#xff0c;展示一个进度条可以帮助我们了解当前任务的进度&#xff0c;以及大约还需要多长时间来完成&#xff0c;R语言提供了几种简单且灵…...

Maven实战-声明周期和插件

Maven实战-声明周期和插件 Maven 设计了插件机制&#xff0c;每个构建步骤都可以绑定一个或者多个插件行为&#xff0c;而且 Maven 为大多数构建步骤编写 并绑定了默认插件。例如&#xff0c;针对编译的插件有 maven-compiler-plugin&#xff0c;针对测试的插件有 maven-sure…...

ebpf的快速开发工具--libbpf-bootstrap

基于ubuntu22.04-深入浅出 eBPF 基于ebpf的性能工具-bpftrace 基于ebpf的性能工具-bpftrace脚本语法 基于ebpf的性能工具-bpftrace实战(内存泄漏) 什么是libbpf-bootstrap libbpf-bootstrap是一个开源项目&#xff0c;旨在帮助开发者快速启动和开发使用eBPF(Extended Berk…...

万界星空科技/生产制造执行MES系统/开源MES/免费MES

开源系统概述&#xff1a; 万界星空科技免费MES、开源MES、商业开源MES、市面上最好的开源MES、MES源代码、免费MES、免费智能制造系统、免费排产系统、免费排班系统、免费质检系统、免费生产计划系统、免费数字化大屏。 万界星空开源MES制造执行系统的Java开源版本。开源mes…...

螺纹快速接头在卫浴行业中的应用提高产量降低生产成本

螺纹快速接头在卫浴行业主要用于上下水测试和密封性测试&#xff0c;可以快速密封连接待测产品和水管。取代之前的工人手拧编织管六角螺母的方式&#xff0c;方便快捷&#xff0c;密封性好&#xff0c;产品测试更稳定。 卫浴行业产品必须具备很好的密封性&#xff0c;防止在实际…...

通达OA 2016网络智能办公系统 handle.php SQL注入漏洞

一、漏洞描述 北京通达信科科技有限公司通达OA2016网络智能办公系统 handle.php 存在sql注入漏洞&#xff0c;攻击者可利用此漏洞获取数据库管理员权限&#xff0c;查询数据、获取系统信息&#xff0c;威胁企业单位数据安全。 二、网络空间搜索引擎查询 fofa查询 app"T…...

parameter的各种用法以及localparam的用法

parameter的各种用法以及localparam的用法 一、这种写法放在v文件或者是用来调用其他的ram文件都是正确的。 一、这种写法放在v文件或者是用来调用其他的ram文件都是正确的。 module para_local();parameter a 10; // 第一种用法 parameter a 4d10; // 第二种用法 para…...

网络社区挖掘-图论部分的基本知识笔记

1 网络社区挖掘定义 网络社区挖掘是指利用数据挖掘技术和机器学习算法&#xff0c;分析社交网络、在线社区或互联网上的各种交互数据&#xff0c;以揭示其中隐藏的模式、关系和信息。这些社区可以是社交媒体平台、在线论坛、博客、微博等&#xff0c;人们在这些平台上进行交流…...

Vue Router - 路由的使用、两种切换方式、两种传参方式、嵌套方式

目录 一、Vue Router 1.1、下载 1.2、基本使用 a&#xff09;引入 vue-router.js&#xff08;注意&#xff1a;要在 Vue.js 之后引入&#xff09;. b&#xff09;创建好路由规则 c&#xff09;注册到 Vue 实例中 d&#xff09;展示路由组件 1.3、切换路由的两种方式 1.…...

mysql为什么会选错索引,以及优化器是如何选择索引的

一&#xff1a;概念 在 索引建立之后&#xff0c;一条语句可能会命中多个索引&#xff0c;这时&#xff0c;索引的选择&#xff0c;就会交由 优化器 来选择合适的索引。 优化器选择索引的目的&#xff0c;是找到一个最优的执行方案&#xff0c;并用最小的代价去执行语句。 二…...

vue基础知识十七:你知道vue中key的原理吗?说说你对它的理解

一、Key是什么 开始之前&#xff0c;我们先还原两个实际工作场景 1.当我们在使用v-for时&#xff0c;需要给单元加上key <ul><li v-for"item in items" :key"item.id">...</li> </ul>2.用new Date()生成的时间戳作为key&#x…...

攻防演练蓝队|Windows应急响应入侵排查

文章目录 日志分析web日志windows系统日志 文件排查进程排查新增、隐藏账号排查启动项/服务/计划任务排查工具 日志分析 web日志 dirpro扫描目录&#xff0c;sqlmap扫描dvwa Python dirpro -u http://192.168.52.129 -b sqlmap -u "http://192.168.52.129/dvwa/vulnera…...

uniapp 小程序实现图片宽度100%、高度自适应的效果

因为image组件默认是有宽度跟高度的&#xff0c;所以这个高度不怎么好写 通过load事件来控制图片的高度 话不多说&#xff0c;直接上代码&#xff0c; <image class"img" src"/static/image.png" :style"{ height: imgHeight px }"mode&q…...