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

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

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

相关文章

一起玩儿Proteus仿真(C51)——06. 红绿灯仿真(二)

摘要&#xff1a;本文介绍如何仿真红绿灯 今天来看一下红绿灯仿真程序的具体实现方法。先来看一下整个程序的原理图。 在这个红绿灯仿真实验中&#xff0c;每个路口需要控制的设备是2位数码管显示倒计时以及红黄绿灯的亮灭。先来看一下数码管的连接方法。 数码管的8根LED显示…

大模型Layer normalization知识

Layer Norm 的计算公式 Layer Norm&#xff08;层归一化&#xff09;是一种用于神经网络中的归一化技术&#xff0c;用于提高模型的训练效果和泛化能力。 RMS Norm 的计算公式 RMS Norm 的作用是通过计算输入 X 的均方根&#xff0c;将每个样本的特征进行归一化&#xff0c;使…

AD域国产替代方案,助力某金融企业麒麟信创电脑实现“真替真用”

近期收到不少企业客户反馈采购的信创PC电脑用不起来&#xff0c;影响信创改造的进度。例如&#xff0c;某金融企业积极响应国产化信创替代战略&#xff0c;购置了一批麒麟操作系统电脑。分发使用中发现了如下问题&#xff1a; • 当前麒麟操作系统电脑无法做到统一身份认证&…

【Java】零基础蓝桥杯算法学习——线性动态规划(一维dp)

线性dp——一维动态规划 1、考虑最后一步可以由哪些状态得到&#xff0c;推出转移方程 2、考虑当前状态与哪些参数有关系&#xff0c;定义几维数组来表示当前状态 3、计算时间复杂度&#xff0c;判断是否需要进行优化。 一维动态规划例题&#xff1a;最大上升子序列问题 Java参…

面试技术栈 —— 2024网易雷火暑期实习真题

面试技术栈 —— 2024网易雷火暑期实习真题 1. 最长递增子序列。2. 集中限流和单机限流你觉得哪个好&#xff1f;3. redis部署服务器配置&#xff0c;为什么不用哨兵&#xff1f;4. 讲讲分布式session的原理。5. 数据库&#xff1a;表数据量大了&#xff0c;如何分表&#xff1…

Python 读取pdf文件

Python 实现读取pdf文件简单示例。 安装命令 需要安装操作pdf的三方类库&#xff0c;命令如下&#xff1a; pip install pdfminer3K 安装过程如下&#xff1a; 引入类库 需要引入很多的类库。 示例如下&#xff1a; import sys import importlib importlib.reload(sys)fr…

cordic算法圆周系统计算sin、cos、平方和开根、atan、坐标系变换

cordic算法圆周系统计算sin、cos、平方和开根、atan 一、cordic圆周系统旋转模式和向量模式1.1 旋转模式1.2 向量模式 二、一些需要考虑的事项2.1角度范围2.2输入正负2.3关于迭代精度2.4坐标系旋转 参考文献&#xff1a; 若想计算 s i n sin sin、 c o s cos cos、 x 2 y 2 \s…

【MySQL】索引事务

MySQL索引事务 1. 索引1.1 概念1.2 作用1.3 使用场景1.4 使用1.5 案例 2. 事务2.2 事物的概念2.3 使用 3. 内容重点总结 1. 索引 1.1 概念 索引是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引&#xff0c; 并指定索引的类…

【leetcode热题100】不同的二叉搜索树

给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;5示例 2&#xff1a; 输入&#xff1a;n 1 输出&#xff1a;1 …

算法学习——LeetCode力扣回溯篇2

算法学习——LeetCode力扣回溯篇2 40. 组合总和 II 40. 组合总和 II - 力扣&#xff08;LeetCode&#xff09; 描述 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字…

Qt 的准备知识

文章目录 1. Qt 背景介绍2. 搭建 Qt 开发环境3. 认识 Qt Creator3.1 main.cpp3.2 widget.h3.3 widget.cpp3.4 Forms3.5 .pro文件 1. Qt 背景介绍 Qt 是⼀个 跨平台的 C 图形用户界面应用程序框架 。它为应用程序开发者提供了建立艺术级图形界⾯所需的所有功能。它是完全⾯向对…

Docker 在window 2024版笔记 下载 安装 操作 配置

---Docker 前言--- Docker windows版官方版是一款专业开源的应用容器引擎&#xff0c;可以加快用户构建、共享和运行现代应用程序的速度&#xff0c;支持运行Linux和Windows Docker容器。 Docker 在容器的基础上&#xff0c;进行了进一步的封装&#xff0c;从文件系统、网络互…

关于Windows Media Player的一些知识,看这篇文章就差不多了

你知道如何在电脑上打开Windows Media Player吗?如果它不是你电脑上默认的媒体播放器,你知道如何将其设为默认吗?此外,如果你找不到它,你知道怎么把它找回来吗?这篇文章将向你展示你想要了解的所有信息。 在这篇文章中,我们将向你展示以下信息: 如何打开Windows Medi…

从傅立叶变换到奥运五环

傅立叶变换的本质 离散傅立叶变换的本质就是用一系列的正弦&#xff08;或者余弦&#xff09;函数的和来拟合一个周期函数f(t)。公式如下&#xff1a; (1) 其中T是f(t)的周期&#xff0c;即f(tT)f(t)对任意t成立。和的周期是。换句话说&#xff0c;后两者的频率是f(t)的频率的…

推荐10个最受欢迎的 Vue.js UI 库

在2024年,随着Vue.js的不断普及和发展,这个轻量级、易于学习的JavaScript框架在前端开发者中的受欢迎程度日益上升。Vue.js之所以受到青睐,很大一部分原因是其庞大的生态系统,特别是众多的UI库,这些库提供了预先构建的组件和工具,帮助开发者快速高效地构建出既美观又响应…

Python算法深度探索:从基础到进阶

引言 本文将引导您从Python的基础算法出发&#xff0c;逐步深入到更复杂的算法领域。我们将探讨数组操作、图算法以及机器学习中的常用算法&#xff0c;并通过实例和代码展示它们在实际应用中的价值。 1. 基础算法&#xff1a;数组操作 数组操作是算法实现中非常基础且重要的一…

Editing While Playing 使用 Easyx 开发的 RPG 地图编辑器 tilemap eaitor

AWSD移动画布 鼠标右键长按拖拽 鼠标左键长按绘制 可以边拖拽边移动画布边绘制。 F1 导出 DLC F2 导入DLC author: 民用级脑的研发记录 1309602336qq.com 开发环境&#xff1a; 内置 easyx 的 devc 5.11 或者 VS 2022 TDM GCC 4.9.2 64-bit c11及以上都可运行 windows 环境运行…

算法-16-并查集

并查集简介 并查集&#xff1a;一开始&#xff0c;把a&#xff0c;b&#xff0c;c放入并查集&#xff0c;a自己一个集合&#xff0c;b自己一个&#xff0c;c自己一个 提供的方法 1.boolean isSameSet(a,b)&#xff0c;判断ab是否在同一个集合 2.void union(a,b),把a所…

Hadoop-Yarn-ResourceManagerHA

在这里先给屏幕面前的你送上祝福&#xff0c;祝你在未来一年&#xff1a;技术步步高升、薪资节节攀升&#xff0c;身体健健康康&#xff0c;家庭和和美美。 一、介绍 在Hadoop2.4之前&#xff0c;ResourceManager是YARN集群中的单点故障 ResourceManager HA是通过 Active/St…

163基于matlab的不同目标函数的盲源信号分离基于负熵的

基于matlab的不同目标函数的盲源信号分离基于负熵的&#xff1b;基于负熵的改进算法&#xff1b; 基于峭度的&#xff1b;基于互信息的&#xff1b;基于非线性PCA的。输出解混前后信号结果。程序已调通&#xff0c;可直接运行。 163 负熵、峭度、互信息、PCA 信号处理 (xiaohon…