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

相关文章

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题是由安全生产模拟考试一点通提供,流动式起重机司机证模拟考试题库是根据流动式起重机司机最新版教材,流动式起重机司机大纲整理而成(含2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题参考答案和部分工种参考解析),掌握本资料和学校方法,考试容易。流动式起重机司机考试技

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来