arkTS开发鸿蒙OS个人商城案例【2024最新 新年限定开发案例QAQ】

2024-02-14 16:20

本文主要是介绍arkTS开发鸿蒙OS个人商城案例【2024最新 新年限定开发案例QAQ】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

龙年前述

源码获取>文章下方二维码,回复关键字“鸿蒙OS商场源码”

前言

arkTS是华为自己研发的一套前端语言,是在js和ts技术的基础上又进行了升级而成!

本篇文章会带领大家通过arkTS+node.js+mongoDB来完成一个鸿蒙OS版本的商城案例!

技术栈

1.arkTS

2.node.js

3.arkTS UI

4.express

5.mongoDB

技术栈讲解

arkTS

ArkTS是HarmonyOS应用开发语言。它在保持TypeScript(简称TS)基本语法风格的基础上,对TS的动态类型特性施加更严格的约束,引入静态类型。同时,提供了声明式UI、状态管理等相应的能力,让开发者可以以更简洁、更自然的方式开发高性能应用。

面向万物互联时代,华为提出一次开发多端部署、可分可合自由流转、统一生态原生智能三大应用与服务开发理念,针对多设备、多入口、服务可分可合等特性,提供多种能力协助开发者降低开发门槛,同时HarmonyOS与OpenHarmony统一生态。HarmonyOS基于JS/TS语言体系,构建了全新的声明式开发语言ArkTS。除了兼容JS/TS语言生态,ArkTS扩展了声明式UI语法和轻量化并发机制。

ArkTS是HarmonyOS主力应用开发语言。为便于熟悉Web前端的开发者快速上手,HarmonyOS在UI开发框架中,还提供了“兼容JS的类Web开发范式”。它通过模板、样式、逻辑三段式来构建相应的应用UI界面,并结合相应的运行时实现了优化的运行体验。

基本语法

装饰器: 用于装饰类、结构、方法以及变量,并赋予其特殊的含义。如上述示例中@Entry、@Component和@State都是装饰器,@Component表示自定义组件,@Entry表示该自定义组件为入口组件,@State表示组件中的状态变量,状态变量变化会触发UI刷新。

UI描述:以声明式的方式来描述UI的结构,例如build方法中的代码块。

自定义组件:可复用的UI单元,可组合其他组件,如上述被@Component装饰的struct Hello。

系统组件:ArkUI框架中默认内置的基础和容器组件,可直接被开发者调用,比如示例中的Column、Text、Divider、Button。

属性方法:组件可以通过链式调用配置多项属性,如fontSize、width、height、backgroundColor等。

事件方法:组件可以通过链式调用设置多个事件的响应逻辑,如跟随在Button后面的onClick。 [4]

声明式UI

创建组件

配置属性

配置事件

配置子组件 [5]

状态管理

状态变量:被状态装饰器装饰的变量,改变会引起UI的渲染更新。

常规变量:没有状态的变量,通常应用于辅助计算。它的改变永远不会引起UI的刷新。

数据源/同步源:状态变量的原始来源,可以同步给不同的状态数据。通常意义为父组件传给子组件的数据。

命名参数机制:父组件通过指定参数传递给子组件的状态变量,为父子传递同步参数的主要手段。示例:CompA: ({ aProp: this.aProp })。

从父组件初始化:父组件使用命名参数机制,将指定参数传递给子组件。本地初始化的默认值在有父组件传值的情况下,会被覆盖。

初始化子节点:组件中状态变量可以传递给子组件,初始化子组件对应的状态变量。示例同上。

本地初始化:变量声明的时候赋值,作为初始化的默认值。示例:@State count: number = 0。 [6]

渲染控制

ArkUI通过自定义组件的build函数和@builder装饰器中的声明式UI描述语句构建相应的UI。在声明式描述语句中开发者除了使用系统组件外,还可以使用渲染控制语句来辅助UI的构建,这些渲染控制语句包括控制组件是否显示的条件渲染语句,基于数组数据快速生成组件的循环渲染语句以及针对大数据量场景的数据懒加载语句

node.js

Node.js发布于2009年5月,由Ryan Dahl开发,是一个基于Chrome V8引擎的JavaScript运行环境,使用了一个事件驱动、非阻塞式I/O模型, [1]让JavaScript 运行在服务端的开发平台,它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。

Node.js对一些特殊用例进行优化,提供替代的API,使得V8在非浏览器环境下运行得更好,V8引擎执行Javascript的速度非常快,性能非常好,基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。

2009年2月,Ryan Dahl在博客上宣布准备基于V8创建一个轻量级的Web服务器并提供一套库。

2009年5月,Ryan Dahl在GitHub上发布了最初版本的部分Node包,随后几个月里,有人开始使用Node开发应用。

2009年11月和2010年4月,两届JSConf大会都安排了Node.js的讲座。

2010年年底,Node获得云计算服务商Joyent资助,创始人Ryan Dahl加入Joyent全职负责Node的发展。

2011年7月,Node在微软的支持下发布Windows版本。

2016年,leftpad事件,Yarn诞生

2021年,发布最新版本Node.js 17 [3]

V8引擎本身使用了一些最新的编译技术。这使得用Javascript这类脚本语言编写出来的代码运行速度获得了极大提升,又节省了开发成本。对性能的苛求是Node的一个关键因素。 Javascript是一个事件驱动语言,Node利用了这个优点,编写出可扩展性高的服务器。Node采用了一个称为“事件循环(event loop)”的架构,使得编写可扩展性高的服务器变得既容易又安全。提高服务器性能的技巧有多种多样。Node选择了一种既能提高性能,又能减低开发复杂度的架构。这是一个非常重要的特性。并发编程通常很复杂且布满地雷。Node绕过了这些,但仍提供很好的性能。

Node采用一系列“非阻塞”库来支持事件循环的方式。本质上就是为文件系统、数据库之类的资源提供接口。向文件系统发送一个请求时,无需等待硬盘(寻址并检索文件),硬盘准备好的时候非阻塞接口会通知Node。该模型以可扩展的方式简化了对慢资源的访问, 直观,易懂。尤其是对于熟悉onmouseover、onclick等DOM事件的用户,更有一种似曾相识的感觉。

虽然让Javascript运行于服务器端不是Node的独特之处,但却是其一强大功能。不得不承认,浏览器环境限制了我们选择编程语言的自由。任何服务器与日益复杂的浏览器客户端应用程序间共享代码的愿望只能通过Javascript来实现。虽然还存在其他一些支持Javascript在服务器端 运行的平台,但因为上述特性,Node发展迅猛,成为事实上的平台。

在Node启动的很短时间内,社区就已经贡献了大量的扩展库(模块)。其中很多是连接数据库或是其他软件的驱动,但还有很多是凭他们的实力制作出来的非常有用的软件。

最后,不得不提到的是Node社区。虽然Node项目还非常年轻,但很少看到对一个项目如此狂热的社区。不管是新手,还是专家,大家都围绕着项目,使用并贡献自己的能力,致力于打造一个探索、支持、分享、听取建议的乐土。

具备书写JavaScript的IDE,普通的记事本也可以进行开发。在几年的时间里,Node.JS逐渐发展成一个成熟的开发平台,吸引了许多开发者。有许多大型高流量网站都采用Node.JS进行开发,此外,开发人员还可以使用它来开发一些快速移动Web框架。

除了Web应用外,NodeJS也被应用在许多方面,本文盘点了NodeJS在其它方面所开发的十大令人神奇的项目,这些项目涉及到应用程序监控、媒体流、远程控制、桌面和移动应用等等。

效果图

鸿蒙端项目架构

shouye.ets

import  axios  from '@ohos/axios'
import router from '@ohos.router'
@Component
export struct app_shouye{@State zhanghao: object = router.getParams()// 设置搜索框的提示内容private changeValue:string = ''@State selectedItemId : number = 0@State one:string = ''// 设置商品的渲染列表Object@State items: Array<Object> = [];aboutToAppear() {axios({method: "get",url: 'http://localhost:3000/shangpins/find_all',}).then(res => {console.info('result:' + JSON.stringify(res.data.data));this.items = res.data.data}).catch(error => {console.error(error);})console.log(JSON.stringify(this.items))}build(){Column(){// 搜索栏Search({ value: this.changeValue, placeholder: '请输入搜索的商品',}).searchButton('搜索').width(300).height(40).backgroundColor('#F5F5F5').placeholderColor(Color.Grey).placeholderFont({ size: 14, weight: 400 }).textFont({ size: 14, weight: 400 }).onSubmit((value: string) => {router.pushUrl({url: 'pages/sousuo',params: {sousuoValue: this.changeValue,}})}).onChange((value: string) => {this.changeValue = valueconsole.log(this.changeValue)}).margin(20)// 显示商品列表List({ space: 20, initialIndex: 0 }){ForEach(this.items, (item) => {ListItem() {Row(){Image(item.img).alt($r('app.media.icon'))// 使用alt,在网络图片加载成功前使用占位图.width(150).height(180)Column({space:10}){Text(item.name).fontWeight(800).margin(20)Text(item.detail)Text('¥:'+item.price).fontColor('red').fontWeight(FontWeight.Bold).fontSize(20)}.width(180)}.alignItems(VerticalAlign.Top)}.onClick(() => {this.selectedItemId = item._id;// 获取点击物品的idthis.one = item._idconsole.log(JSON.stringify(this.one))router.pushUrl({url: 'pages/detail',params: {id: this.one,zhanghao:this.zhanghao?.['zhanghao']}})})})}.height('90%').listDirection(Axis.Vertical) // 排列方向.divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线.edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果}.width('98%').height('100%')}}

fenlei.ets

import  axios  from '@ohos/axios'
import router from '@ohos.router'
@Component
export struct app_shouye{@State zhanghao: object = router.getParams()// 设置搜索框的提示内容private changeValue:string = ''@State selectedItemId : number = 0@State one:string = ''// 设置商品的渲染列表Object@State items: Array<Object> = [];aboutToAppear() {axios({method: "get",url: 'http://localhost:3000/shangpins/find_all',}).then(res => {console.info('result:' + JSON.stringify(res.data.data));this.items = res.data.data}).catch(error => {console.error(error);})console.log(JSON.stringify(this.items))}build(){Column(){// 搜索栏Search({ value: this.changeValue, placeholder: '请输入搜索的商品',}).searchButton('搜索').width(300).height(40).backgroundColor('#F5F5F5').placeholderColor(Color.Grey).placeholderFont({ size: 14, weight: 400 }).textFont({ size: 14, weight: 400 }).onSubmit((value: string) => {router.pushUrl({url: 'pages/sousuo',params: {sousuoValue: this.changeValue,}})}).onChange((value: string) => {this.changeValue = valueconsole.log(this.changeValue)}).margin(20)// 显示商品列表List({ space: 20, initialIndex: 0 }){ForEach(this.items, (item) => {ListItem() {Row(){Image(item.img).alt($r('app.media.icon'))// 使用alt,在网络图片加载成功前使用占位图.width(150).height(180)Column({space:10}){Text(item.name).fontWeight(800).margin(20)Text(item.detail)Text('¥:'+item.price).fontColor('red').fontWeight(FontWeight.Bold).fontSize(20)}.width(180)}.alignItems(VerticalAlign.Top)}.onClick(() => {this.selectedItemId = item._id;// 获取点击物品的idthis.one = item._idconsole.log(JSON.stringify(this.one))router.pushUrl({url: 'pages/detail',params: {id: this.one,zhanghao:this.zhanghao?.['zhanghao']}})})})}.height('90%').listDirection(Axis.Vertical) // 排列方向.divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线.edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果}.width('98%').height('100%')}}

gouwuche.ets

import router from '@ohos.router'
import  axios  from '@ohos/axios'
import { Header } from '../components/Toubu'
@Component
export struct gouwuche{@State zhanghao: object = router.getParams()// 设置商品的渲染列表Object@State items: Array<Object> = [];aboutToAppear() {axios({method: "post",url: 'http://localhost:3000/gouwuche/find',data:{username:this.zhanghao?.['zhanghao']}}).then(res => {console.info('result1111:' + JSON.stringify(res.data.data));this.items = res.data.data}).catch(error => {console.error(error);})console.log(JSON.stringify(this.items))}build(){//   标题部分Column(){// 自定义组件之间传参// Header({message:true})Image($r('app.media.shuaxin')).width(30).margin(20).onClick(() =>{axios({method: "post",url: 'http://localhost:3000/gouwuche/find',data:{username:this.zhanghao?.['zhanghao']}}).then(res => {console.info('result1111:' + JSON.stringify(res.data.data));this.items = res.data.data}).catch(error => {console.error(error);})})// Text(this.zhanghao?.['zhanghao'])List({ space: 20, initialIndex: 0 }){ForEach(this.items, (item) => {ListItem() {Row(){Image(item.img).alt($r('app.media.icon'))// 使用alt,在网络图片加载成功前使用占位图.width(150).height(180)Column({space:10}){Text(item.name).fontWeight(800).margin(20)Text(item.detail)Text('¥:'+item.price).fontColor('red').fontWeight(FontWeight.Bold).fontSize(20)}.width(180)}.alignItems(VerticalAlign.Top)}})}.height('85%').listDirection(Axis.Vertical) // 排列方向.divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线.edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果Row({space:30}){Button('清除购物车', { type: ButtonType.Normal, stateEffect: true }).borderRadius(8).backgroundColor(0x317aff).width(150).onClick(() => {console.log('ButtonType.Normal')})Button('立即付款', { type: ButtonType.Normal, stateEffect: true }).borderRadius(8).backgroundColor(0x317aff).width(150).onClick(() => {console.log('ButtonType.Normal')})}}.width('100%').height('100%')}
}

Toubu.ets

import router from '@ohos.router'
@Component
export struct Header{@State message: Boolean = falsebuild(){//   标题部分Row({space:5}){Image($r('app.media.fanhui')).width(20).onClick(() =>{router.back()})Blank()Image($r('app.media.shuaxin')).width(30).onClick(() =>{router.back()})}.width('98%').height(30)}
}

wode.ets

import router from '@ohos.router'
@Component
export struct app_wode{@State zhanghao: object = router.getParams()build(){//   标题部分Column(){Row(){Row({space:10}){Image($r('app.media.icon')).width(50).height(50)Text('昵称:'+ this.zhanghao?.['zhanghao']).margin({left:20}).fontColor('#fff')}.margin({top:30,left:50})}.width('100%').height(180).backgroundImage('./components/img/app_wo_bj.jpg').backgroundImageSize(ImageSize.Cover)Row({space:50}){Image($r('app.media.icon')).width(50).height(50)Text('购物记录').fontSize(18)}.width('100%').backgroundColor("#fff").margin({top:20,bottom:20}).padding({left:20,right:20,top:10,bottom:10}).onClick(()=>{router.pushUrl({url: 'pages/GouwuJilu',})console.log('123')})Row({space:50}){Image($r('app.media.icon')).width(50).height(50)Text('修改信息').fontSize(18)}.width('100%').backgroundColor("#fff").margin({bottom:20}).padding({left:20,right:20,top:10,bottom:10}).onClick(()=>{router.pushUrl({url: 'pages/XiugaiXinxi',})console.log('123')})Row({space:50}){Image($r('app.media.icon')).width(50).height(50)Text('退出登录').fontSize(18)}.width('100%').backgroundColor("#fff").margin({bottom:20}).padding({left:20,right:20,top:10,bottom:10}).onClick(()=>{router.replace({url: 'pages/Index',})console.log('123')})}.alignItems(HorizontalAlign.Start).width('100%').height('100%').backgroundColor('#f3f3f3')}
}

detail.ets

import { Header } from '../components/Toubu'
import router from '@ohos.router'
import  axios  from '@ohos/axios'
@Entry
@Component
struct Detail {@State shangpin_detail: object = router.getParams()@State items:Array<Object> = []build() {Row() {Column() {Header()Text(this.shangpin_detail?.['zhanghao'])Text(this.items[0]?.['name'])Flex({ wrap: FlexWrap.NoWrap }) { // 子组件单行布局Text('').width('20%')List({ space: 20, initialIndex: 0 }) {ForEach(this.items, (item) => {ListItem() {Column() {Image(item.img).alt($r('app.media.icon')) // 使用alt,在网络图片加载成功前使用占位图.width(300).height(300)Text(item.name).fontWeight(800).margin(20)Text('¥:' + item.price).fontColor('red').fontWeight(FontWeight.Bold).fontSize(20)Text(item.detail)}}})}.height('85%').listDirection(Axis.Vertical) // 排列方向.divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线.edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果Text('').width('20%')}//   加入购物车,立即购买Row({space:30}){Button('加入购物车', { type: ButtonType.Normal, stateEffect: true }).borderRadius(8).backgroundColor(0x317aff).width(150).onClick(() => {axios({method: "post",url: 'http://localhost:3000/gouwuche/publish/',data: {username: this.shangpin_detail?.['zhanghao'],name:this.items[0]?.['name'],detail:this.items[0]?.['detail'],img:this.items[0]?.['img'],select_classify:this.items[0]?.['select_classify'],price:this.items[0]?.['price']}}).then(res => {console.log(JSON.stringify(res.data.data));this.items = res.data.data}).catch(error => {console.error(error);});console.log('ButtonType.Normal')})Button('立即购买', { type: ButtonType.Normal, stateEffect: true }).borderRadius(8).backgroundColor(0x317aff).width(150).onClick(() => {console.log('ButtonType.Normal')})}}.width('100%')}.height('100%')}onPageShow(){axios({method: "post",url: 'http://localhost:3000/shangpins/find_detail/',data: {_id: this.shangpin_detail?.['id']}}).then(res => {console.log(JSON.stringify(res.data.data));this.items = res.data.data}).catch(error => {console.error(error);});}
}

GouwuJilu.ets

import { Header } from '../components/Toubu'
@Entry
@Component
struct GouwuJilu {@State message: string = '购物记录'build() {Column() {Header()Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)}.width('100%').height('100%')}
}

Index.ets

import  axios  from '@ohos/axios'
import router from '@ohos.router'
@Entry
@Component
struct Index {// 上传数据@State zhanghao: string = ''@State mima: string = ''@State zhanghao_find:string =''@State mima_find:string =''build() {Column() {Text('龙年千帆启鸿蒙').margin({top:70}).fontWeight(FontWeight.Bold).fontSize(30)Image($r('app.media.icon')).width(150).margin({top:50,bottom:20})// 账号登录TextInput({placeholder:'账号'}).margin(20).height(50).onChange(value =>{console.log(value)this.zhanghao_find = value}).backgroundColor('#36D2')TextInput({placeholder:'密码'}).margin({left:20,right:20,bottom:25}).height(50).onChange(value =>{console.log(value)this.mima_find = value}).backgroundColor('#36D2')Button('登录').width(200).onClick(()=>{axios({method: "get",url: 'http://localhost:3000/users/find/'+this.zhanghao_find+ '/' + this.mima_find,}).then(res => {// console.info('result:' + JSON.stringify(res.data));console.info('result:' + JSON.stringify(res.data));// 获取data数组中的第一个元素const firstData = res.data.data[0];// 获取zhanghao字段的值const zhanghaoValue = firstData.zhanghao;console.log('zhanghaoValue:', zhanghaoValue);// 获取data数组中的第一个元素// 获取zhanghao字段的值router.pushUrl({url: 'pages/NewApp_one',params: {zhanghao: zhanghaoValue,}})}).catch(error => {console.error(error);})})Row(){Text('注册').margin({right:5}).onClick( () =>{{router.pushUrl({url: 'pages/zhuce',})}})Text('|')Text('忘记密码').margin({left:5}).onClick( () =>{{router.pushUrl({url: 'pages/WangjiMima',})}})}.margin(20)}.width('100%').height('100%')}
}

NewApp_one.ets

import { app_shouye } from '../components/shouye/shouye'
import { app_wode } from '../components/wode'
import { app_fenlei } from '../components/fenlei'
import { gouwuche } from '../components/gouwuche'
import router from '@ohos.router'@Entry
@Component
struct NewApp_one {// 获取上一个页面传过来的该登录的用户名@State zhanghao: object = router.getParams()build() {Column() {Tabs({ barPosition: BarPosition.End }) {TabContent() {app_shouye({ zhanghao: this.zhanghao?.['zhanghao'] })}.tabBar((new BottomTabBarStyle($r('sys.media.ohos_app_icon'),'首页')))TabContent() {app_fenlei()}.tabBar((new BottomTabBarStyle($r('sys.media.ohos_app_icon'),'分类')))TabContent() {gouwuche({ zhanghao: this.zhanghao?.['zhanghao'] })}.tabBar((new BottomTabBarStyle($r('sys.media.ohos_app_icon'),'购物车')))TabContent() {app_wode({ zhanghao: this.zhanghao?.['zhanghao'] })}.tabBar((new BottomTabBarStyle($r('sys.media.ohos_app_icon'),'我的')))}}.width('100%').height('100%')}onPageShow(){console.log('这是父组件显示页面生命周期函数')}
}

sousuo.ets

import router from '@ohos.router'
import  axios  from '@ohos/axios'
import { Header } from '../components/Toubu'
@Entry
@Component
struct Sousuo {@State sousuoValue: object = router.getParams()@State items:Array<Object> = []@State selectedItemId : number = 0@State one:string = ''private changeValue:string = this.sousuoValue?.['sousuoValue']build() {Column() {Header()Search({ value: this.changeValue, placeholder: '请输入搜索的商品',}).searchButton('搜索').width(300).height(40).backgroundColor('#F5F5F5').placeholderColor(Color.Grey).placeholderFont({ size: 14, weight: 400 }).textFont({ size: 14, weight: 400 })// 点击搜索.onSubmit((value: string) => {axios({method: "post",url: 'http://localhost:3000/shangpins/products/',data: {changeValue: this.changeValue}}).then(res => {console.log(JSON.stringify(res.data.data));this.items = res.data.data}).catch(error => {console.error(error);});})// 输入搜索.onChange((value: string) => {this.changeValue = valueconsole.log(this.changeValue)axios({method: "post",url: 'http://localhost:3000/shangpins/products/',data: {changeValue: value}}).then(res => {console.log(JSON.stringify(res.data.data));this.items = res.data.data}).catch(error => {console.error(error);});}).margin(20)List({ space: 20, initialIndex: 0 }){ForEach(this.items, (item) => {ListItem() {Row(){Image(item.img).alt($r('app.media.icon'))// 使用alt,在网络图片加载成功前使用占位图.width(150).height(180)Column({space:10}){Text(item.name).fontWeight(800).margin(20)Text(item.detail)Text('¥:'+item.price).fontColor('red').fontWeight(FontWeight.Bold).fontSize(20)}.width(180)}.alignItems(VerticalAlign.Top)}.onClick(() => {this.selectedItemId = item._id;// 获取点击物品的idthis.one = item._idconsole.log(JSON.stringify(this.one))router.pushUrl({url: 'pages/detail',params: {id: this.one,}})})})}.height('90%').listDirection(Axis.Vertical) // 排列方向.divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线.edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果}.width('100%').height('100%')}//上一个页面跳转过来之后查询的数据onPageShow() {console.log('wwww' + this.sousuoValue?.['sousuoValue']);axios({method: "post",url: 'http://localhost:3000/shangpins/products/',data: {changeValue: this.sousuoValue?.['sousuoValue'] // 修正获取参数的方式}}).then(res => {console.log(JSON.stringify(res.data.data));this.items = res.data.data}).catch(error => {console.error(error);});}}

WangjiMima.ets

import { Header } from '../components/Toubu'
import  axios  from '@ohos/axios'
import router from '@ohos.router'
@Entry
@Component
struct Index {// 上传数据@State zhanghao: string = ''@State mima: string = ''build() {Column() {Header().margin(20)TextInput({placeholder:'原账号'}).margin(20).height(50).onChange(value =>{console.log(value)this.zhanghao = value}).backgroundColor('#36D2')TextInput({placeholder:'新密码'}).margin({ left:20,right:20,bottom:20 }).height(50).onChange(value =>{console.log(value)this.mima = value}).backgroundColor('#36D2')Button('修改密码').width(200).onClick(()=>{axios({method: "post",url: 'http://localhost:3000/users/upd',data:{zhanghao:this.zhanghao,newmima:this.mima},}).then(res => {console.info('result:' + JSON.stringify(res.data));{router.pushUrl({url: 'pages/NewApp_one',})}}).catch(error => {console.error(error);})})}.width('100%').height('100%')}
}

XiugaiXinxi.ets

import { Header } from '../components/Toubu'
@Entry
@Component
struct XiugaiXinxi {@State message: string = '修改信息'build() {Column() {Header()Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)}.width('100%').height('100%')}
}

zhuce.ets

import { Header } from '../components/Toubu'
import  axios  from '@ohos/axios'
import router from '@ohos.router'
@Entry
@Component
struct Index {// 上传数据@State zhanghao: string = ''@State mima: string = ''@State zhanghao_find:string =''@State mima_find:string =''build() {Column() {Header().margin(20)TextInput({placeholder:'注册账号'}).margin(20).height(50).onChange(value =>{console.log(value)this.zhanghao = value}).backgroundColor('#36D2')TextInput({placeholder:'注册密码'}).margin({ left:20,right:20,bottom:20 }).height(50).onChange(value =>{console.log(value)this.mima = value}).backgroundColor('#36D2')Button('注册并登录').width(200).onClick(()=>{axios({method: "post",url: 'http://localhost:3000/users/publish',data:{zhanghao:this.zhanghao,mima:this.mima},}).then(res => {console.info('result:' + JSON.stringify(res.data));router.pushUrl({url: 'pages/NewApp_one',})}).catch(error => {console.error(error);})})}.width('100%').height('100%')}
}

node.js后端架构

fenlei_api.js

// user_api.js
const express = require('express');
const router = express.Router();
const { fenlei } = require('../db');router.use(express.urlencoded({ extended: true }));
router.use(express.json());// 全部查询
router.get("/find_all", async (req, res) => { // Corrected function signaturetry {const results = await fenlei.find();if (results.length > 0) {// 如果找到匹配的记录,则返回所有匹配的记录res.json({ data: results, message: "登录成功!" });} else {res.status(404).json({ message: "未找到匹配的记录" });}} catch (error) {res.status(500).json({ message: "服务器内部错误" });}});// 指定查询
router.get("/find/:name", async (req, res) => {try {const name = req.params.name;// 使用 find 查询所有匹配指定 name 的数据记录const results = await fenlei.find({ name });if (results.length > 0) {// 如果找到匹配的记录,则返回所有匹配的记录res.json({ data: results, message: "登录成功!" });} else {res.status(404).json({ message: "未找到匹配的记录" });}} catch (error) {res.status(500).json({ message: "服务器内部错误" });}
});module.exports = router;

gouwuche_api.js

// user_api.js
const express = require('express');
const router = express.Router();
const { gouwuche } = require('../db');router.use(express.urlencoded({ extended: true }));
router.use(express.json());// 全部查询
router.post("/find", async (req, res) => {try {const { username } = req.body;// 使用 find 查询所有匹配指定 select_classify 的数据记录const results = await gouwuche.find({ username });if (results.length > 0) {// 如果找到匹配的记录,则返回所有匹配的记录res.json({ data: results, message: "登录成功!" });} else {res.status(404).json({ message: "未找到匹配的记录" });}} catch (error) {res.status(500).json({ message: "服务器内部错误" });}});
//   添加到购物车
router.post("/publish", async (req, res) => {try {const { username,name,detail,img,select_classifyprice,price } = req.body;await gouwuche.create({username,name,detail,img,select_classifyprice,price});res.send("success");} catch (error) {res.send(error, "error");}
});module.exports = router;

shangpin_api.js

// user_api.js
const express = require('express');
const router = express.Router();
const { shangpin } = require('../db');router.use(express.urlencoded({ extended: true }));
router.use(express.json());// 全部查询
router.get("/find_all", async (req, res) => { // Corrected function signaturetry {const results = await shangpin.find();if (results.length > 0) {// 如果找到匹配的记录,则返回所有匹配的记录res.json({ data: results, message: "登录成功!" });} else {res.status(404).json({ message: "未找到匹配的记录" });}} catch (error) {res.status(500).json({ message: "服务器内部错误" });}
});// 指定查询
router.post("/find", async (req, res) => {try {const { select_classify } = req.body;// 使用 find 查询所有匹配指定 select_classify 的数据记录const results = await shangpin.find({ select_classify });if (results.length > 0) {// 如果找到匹配的记录,则返回所有匹配的记录res.json({ data: results, message: "登录成功!" });} else {res.status(404).json({ message: "未找到匹配的记录" });}} catch (error) {res.status(500).json({ message: "服务器内部错误" });}
});// 指定商品详情查询
router.post("/find_detail", async (req, res) => {try {const { _id } = req.body;// 使用 find 查询所有匹配指定 _id 的数据记录const results = await shangpin.find({ _id });if (results.length > 0) {// 如果找到匹配的记录,则返回所有匹配的记录res.json({ data: results, message: "登录成功!" });} else {res.status(404).json({ message: "未找到匹配的记录" });}} catch (error) {res.status(500).json({ message: "服务器内部错误" });}
});//模糊查询
router.post('/products', async (req, res) => {try {const changeValue = req.body.changeValue; // 修正获取请求体中的参数方式// 使用正则表达式进行模糊查询const results = await shangpin.find({ name: { $regex: changeValue, $options: 'i' } });if (results.length > 0) {// 如果找到匹配的记录,则返回所有匹配的记录res.json({ data: results, message: "查询成功!" });} else {res.status(404).json({ message: "未找到匹配的记录" });}} catch (error) {console.error(error);res.status(500).json({ message: "服务器内部错误" });}
});module.exports = router;

user_api.js

// user_api.js
const express = require('express');
const router = express.Router();
const { users } = require('../db');router.use(express.urlencoded({ extended: true }));
router.use(express.json());// 注册账号
router.post("/publish", async (req, res) => {try {const { zhanghao, mima } = req.body;await users.create({zhanghao, mima});res.send("success");} catch (error) {res.send(error, "error");}
});// 注销账号
router.post("/del", async (req, res) => {console.log(req.body.zhanghao);try {const { zhanghao } = req.body;// 使用 deleteOne 删除指定 name 的数据const result = await users.deleteOne({ zhanghao });if (result.deletedCount === 1) {res.send("success");} else {res.send("未找到匹配的记录");}} catch (error) {res.send(error, "error");}
});// 修改账号密码
router.post("/upd", async (req, res) => {try {const { zhanghao, newmima } = req.body;// 使用 updateOne 更新指定 name 的数据记录的 nianling 字段const result = await users.updateOne({ zhanghao }, { $set: { mima: newmima } });res.json({ message: "密码更新成功!", result });} catch (error) {res.status(500).json({ error: error.message });}
});// 账号登录
router.get("/find/:zhanghao/:mima", async (req, res) => {try {const zhanghao = req.params.zhanghao;const mima = req.params.mima;// 使用 find 查询所有匹配指定 name 的数据记录const results = await users.find({ zhanghao, mima });if (results.length > 0) {// 如果找到匹配的记录,则返回所有匹配的记录res.json({ data: results, message: "登录成功!" });} else {res.status(404).json({ message: "未找到匹配的记录" });}} catch (error) {res.status(500).json({ message: "服务器内部错误" });}
});module.exports = router;

db.js

const mongoose = require('mongoose')//连接mongodb数据库
mongoose.connect("mongodb://localhost:27017/node_one").then(() => {console.log("数据库连接成功!")}).catch((err) => {console.log("数据库连接失败!", err)})// 创建表用户表
const Users = new mongoose.Schema({zhanghao: {type: String,},mima: {type: String},
})
// 创建商品表
const Shangpin = new mongoose.Schema({name: {type: String,},detail: {type: String},img:{type: String},select_classify:{type: String},price:{type: String }
})
//创建分类表
const Fenlei = new mongoose.Schema({name: {type: String,},
})
// 创建购物车表
const Gouwuche = new mongoose.Schema({username:{type: String,},name: {type: String,},detail: {type: String},img:{type: String},select_classify:{type: String},price:{type: String }
})const users = mongoose.model("Users", Users);
const shangpin = mongoose.model("Shangpin", Shangpin);
const fenlei = mongoose.model("Fenlei", Fenlei);
const gouwuche = mongoose.model("Gouwuche", Gouwuche);
module.exports = {users,shangpin,fenlei,gouwuche
}

index.js

// index.js
const express = require('express');
const app = express();
const userApi = require('./user_ctrl/user_api');
const shangpinApi = require('./shangpin_ctrl/shangpin_api');
const fenleiApi = require('./fenlei_ctrl/fenlei_api');
const gouwucheApi = require('./gouwuche_ctrl/gouwuche_api');app.use('/users', userApi);app.use('/shangpins', shangpinApi);app.use('/gouwuche', gouwucheApi);app.use('/fenleis', fenleiApi);app.listen(3000, () => {console.log('server running');
});

后端安装指令

1. 下载node.js框架

npm install express --save

2. 下载nodemon解决node代码更新的痛点

npm install nodemon -g

3. node.js连接mongodb数据库

npm install mongoose --save

这篇关于arkTS开发鸿蒙OS个人商城案例【2024最新 新年限定开发案例QAQ】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

Python中使用正则表达式精准匹配IP地址的案例

《Python中使用正则表达式精准匹配IP地址的案例》Python的正则表达式(re模块)是完成这个任务的利器,但你知道怎么写才能准确匹配各种合法的IP地址吗,今天我们就来详细探讨这个问题,感兴趣的朋... 目录为什么需要IP正则表达式?IP地址的基本结构基础正则表达式写法精确匹配0-255的数字验证IP地

MySQL高级查询之JOIN、子查询、窗口函数实际案例

《MySQL高级查询之JOIN、子查询、窗口函数实际案例》:本文主要介绍MySQL高级查询之JOIN、子查询、窗口函数实际案例的相关资料,JOIN用于多表关联查询,子查询用于数据筛选和过滤,窗口函... 目录前言1. JOIN(连接查询)1.1 内连接(INNER JOIN)1.2 左连接(LEFT JOI

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

鸿蒙中Axios数据请求的封装和配置方法

《鸿蒙中Axios数据请求的封装和配置方法》:本文主要介绍鸿蒙中Axios数据请求的封装和配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.配置权限 应用级权限和系统级权限2.配置网络请求的代码3.下载在Entry中 下载AxIOS4.封装Htt

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La