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.rhkb.cn/news/257453.html

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

相关文章

【MySQL】索引事务

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

Django视图

HttpRequests对象 利用http协议向服务器传参的4种途径 提取url特定部分&#xff0c;如/web/index/&#xff0c;可以通过在服务器端的路由中用正则表达式截取查询字符串&#xff0c;形如?key1value&keyvalue2&#xff0c;&#xff08;&#xff1f;前面是路由&#xff0c;…

Pycharm里如何设置多Python文件并行运行

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 夕阳何事近黄昏&#xff0c;不道人间犹有未招魂。 大家好&#xff0c;我是皮皮。 一、前言 相信使用Pycharm的粉丝们肯定有和我一样的想法&#xff0c;…

在Ubuntu22.04上部署FoooCUS2.1

Fooocus 是一款基于 Gradio的图像生成软件&#xff0c;Fooocus 是对 Stable Diffusion 和 Midjourney 设计的重新思考&#xff1a; 1、从 Stable Diffusion 学习&#xff0c;该软件是离线的、开源的和免费的。 2、从 Midjourney 中学到&#xff0c;不需要手动调整&#xff0c;…

2024牛客寒假算法基础集训营3部分题解

智乃与瞩目狸猫、幸运水母、月宫龙虾 链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 Ubuntu是一个以桌面应用为主的Linux发行版操作系统&#xff0c;其名称来自非洲南部祖鲁语或豪萨语的"ubuntu"一词&#xff0c;意思是"人性…

【C++】内存五大区详解

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

Flutter学习(八)Flutter_Boost接入

背景 基于安卓的原生项目&#xff0c;进行Flutter的接入&#xff0c;进行混合开发。 参考链接 官方地址&#xff1a;link fullter_boost配置&#xff1a;link git代理配置&#xff1a;link kotlin语法集成&#xff1a;link 混合开发的坑&#xff1a;link 开发环境 as4…

【从Python基础到深度学习】7. 使用scp命令实现主机间通讯

一、生成 SSH 密钥对 ssh-keygen 是一个用于生成 SSH 密钥对的命令行工具&#xff0c;用于身份验证和加密通信 ssh-keygen 二、将本地主机上的 SSH 公钥添加到远程主机 ssh-copy-id 命令用于将本地主机上的 SSH 公钥添加到远程主机上的 authorized_keys 文件中&#xff0c;…

第12讲创建图文投票实现

创建图文投票实现 图文投票和文字投票基本一样&#xff0c;就是在投票选项里面&#xff0c;多了一个选项图片&#xff1b; <view class"option_item" v-for"(item,index) in options" :key"item.id"><view class"option_input&qu…

【漏洞复现】狮子鱼CMS某SQL注入漏洞

Nx01 产品简介 狮子鱼CMS&#xff08;Content Management System&#xff09;是一种网站管理系统&#xff0c;它旨在帮助用户更轻松地创建和管理网站。该系统拥有用户友好的界面和丰富的功能&#xff0c;包括页面管理、博客、新闻、产品展示等。通过简单直观的管理界面&#xf…

golang集成sentry: go-redis

网上没有找到go-redis集成sentry的库&#xff0c; 所以我简单实现了一个 代码&#xff1a; https://github.com/Shujie-Tan/go-redis-sentry 使用方法&#xff1a; import (redis_sentry "github.com/Shujie-Tan/go-redis-sentry" ) rdb : redis.NewClient(&re…

【C语言】模拟实现库函数qsort

qsort的头文件是stdlib.h 他的四个参数分别是要进行排序的数组base的首地址&#xff0c;base数组的元素个数&#xff0c;每个元素的大小&#xff0c;以及一个函数指针&#xff0c;这个函数指针指向了一个函数&#xff0c;这个函数的参数是两个void*类型的指针&#xff0c;返回类…

【C语言】常见字符串函数的功能与模拟实现

目录 1.strlen() 模拟实现strlen() 2.strcpy() 模拟实现strcpy() 3.strcat() 模拟实现strcat() 4.strcmp() 模拟实现strcmp() 5.strncpy() 模拟实现strncpy() 6.strncat() 模拟实现strncat() 7.strncmp() 模拟实现strncmp() 8.strstr() 模拟实现strstr() 9.str…

数据密集型应用系统设计

数据密集型应用系统设计 原文完整版PDF&#xff1a;https://pan.quark.cn/s/d5a34151fee9 这本书的作者是少有的从工业界干到学术界的牛人&#xff0c;知识面广得惊人&#xff0c;也善于举一反三&#xff0c;知识之间互相关联&#xff0c;比如有个地方把读路径比作programming …

基于 Python 的大数据的电信反诈骗系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

three.js 箭头ArrowHelper的实践应用

效果&#xff1a; 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div></div></el-main></…

Linux系统安全:安全技术 和 防火墙

一、安全技术 入侵检测系统&#xff08;Intrusion Detection Systems&#xff09;&#xff1a;特点是不阻断任何网络访问&#xff0c;量化、定位来自内外网络的威胁情况&#xff0c;主要以提供报警和事后监督为主&#xff0c;提供有针对性的指导措施和安全决策依据,类 似于监控…

【Java】零基础蓝桥杯算法学习——二分查找

算法模板一: // 数组arr的区间[0,left-1]满足arr[i]<k,[left,n-1]满足arr[i]>k;Scanner scan new Scanner(System.in);int[] arr {1,2,3,4,5};int left 0,right arr.length-1;int k scan.nextInt();while(left<right) {//leftright时退出循环int mid (leftrigh…

Hadoop:认识MapReduce

MapReduce是一个用于处理大数据集的编程模型和算法框架。其优势在于能够处理大量的数据&#xff0c;通过并行化来加速计算过程。它适用于那些可以分解为多个独立子任务的计算密集型作业&#xff0c;如文本处理、数据分析和大规模数据集的聚合等。然而&#xff0c;MapReduce也有…

开源免费的Linux服务器管理面板分享

开源免费的Linux服务器管理面板分享 一、1Panel1.1 1Panel 简介1.2 1Panel特点1.3 1Panel面板首页1.4 1Panel使用体验 二、webmin2.1 webmin简介2.2 webmin特点2.3 webmin首页2.4 webmin使用体验 三、Cockpit3.1 Cockpit简介3.2 Cockpit特点3.3 Cockpit首页3.4 Cockpit使用体验…