【鴻蒙應用ArkTS開發系列】- 云開發入門實戰二 實現省市地區三級聯動地址選擇器組件(下)

文章目錄

  • 概述
  • 端云調用流程
  • 端側集成AGC SDK
  • 端側省市地區聯動的地址選擇器組件開發
    • 創建省市數據模型
    • 創建省市地區視圖UI子組件
    • 創建頁面UI視圖Page文件
  • 打包測試
  • 總結

概述

我們在前面的課程,對云開發的入門做了介紹,以及使用一個省市地區聯動的地址選擇器示例,為大家演示了如何創建云開發工程,以及云數據庫、云函數的開發實戰。如果有讀者還沒看過前面的這兩篇文章,那在讀這篇文章之前,建議先看下以下這兩篇文章,之后再來閱讀本篇文章,會更好理解云開發這塊的內容。
《【鴻蒙應用ArkTS開發系列】- 云開發入門簡介》
《【鴻蒙應用ArkTS開發系列】- 云開發入門實戰二 實現省市地區三級聯動地址選擇器組件(上)》

那我們現在正式開始今天的課程,本次課程是 《【鴻蒙應用ArkTS開發系列】- 云開發入門實戰二 實現省市地區三級聯動地址選擇器組件(上)》 的下篇,上篇我們完成了省市地區聯動的地址選擇器云工程的云數據、云函數的開發跟部署,這次的課程,我們將開發一個鴻蒙客戶端,來調用云服務的API,獲取地址信息數據進行展示。

通過本次課程,我們將學習到以下內容:

  1. 鴻蒙客戶端如何集成AGC SDK;
  2. 鴻蒙客戶端如何調用云函數獲取數據;
  3. 實現省市地區聯動的地址選擇器組件;
  4. ArkUI @Provide、@Consume、@Watch等狀態管理裝飾器的使用

那下面我們直接進入本次課程的學習。按照慣例,這里先上成品效果圖:

在這里插入圖片描述
上面由于是用的云端地址位置數據,因此會有一個加載的過程,實際開發時,我們也可以將地址數據內置到客戶端中,或者網絡數據做一個緩存處理,這樣用戶體驗會更好一些。

端云調用流程

下面我們先看下客戶端跟云服務之間的一個交互流程圖:
在這里插入圖片描述

端側集成AGC SDK

客戶端工程應該怎么集成AGC SDK呢,這一步,我建議還是跟《【鴻蒙應用ArkTS開發系列】- 云開發入門簡介》 中提到的,使用端云一體化開發目標來創建工程,這樣 DevEco Studio會為端側工程自動集成AGC相關云服務最新版本SDK。

  1. “entry/src/main/resources/rawfile/agconnect-services.json”:AGC
    SDK配置文件,內含client_secret和api_key,請妥善保管。
    在這里插入圖片描述
  2. “entry/oh-package.json5”:自動引入了AGC相關云服務(認證服務、云函數、云存儲)最新版本SDK,同時會自動集成端云一體化登錄組件的最新SDK。
    工程同步成功后可以看到當前從ohpm倉獲取的最新版本。
    在這里插入圖片描述
    上圖是之前創建的,現在的版本的已經有所更新,大家根據IDE實際創建的版本來。我目前工程集成的SDK是下面這樣的
    在這里插入圖片描述
    如果是已經存在的端側工程,那需要按照官網的AGC SDK 集成方式集成,包括從AppGallery-Connect 中下載項目agconnect-services.json文件導入到端側工程,以及對應的AGC SDK庫進行 ohpm依賴安裝。
    在這里插入圖片描述官網 HarmonyOS使用入門(ArkTS API9及以上) 對鴻蒙集成AGC服務 講解的很詳細,這里就不過多贅述,大家直接看官方文檔即可。

做完前期工作,那我們開始進入本篇課程的重點內容,開發一個省市地區聯動的地址選擇器組件。

端側省市地區聯動的地址選擇器組件開發

創建省市數據模型

打開DevEco Studio,在"Application-> entry -> src -> main -> ets 下創建一個bean目錄,用于存放省市數據的數據模型類,在目錄中創建ProvinceBean(省)、CityBean(市)、DistrictBean(區縣),

在這里插入圖片描述

完成代碼如下:

ProvinceBean.ts

/*** 省份信息*/
export class ProvinceBean {public id: number;public code: string;public label: string;
}

CityBean.ts

/*** 城市信息*/
export class CityBean {public id: number;public province_code: string;public code: string;public label: string;
}

DistrictBean.ts

/*** 區縣信息*/
export class DistrictBean {public id: number;public city_code: string;public code: string;public label: string;
}

創建省市地區視圖UI子組件

打開DevEco Studio,在"Application-> entry -> src -> main -> ets "目錄下新建一個"component"文件夾來存放省份UI子組件、城市UI子組件、區縣UI子組件。
在這里插入圖片描述
在component目錄上右鍵,點擊New ->ArkTS File 菜單, 創建三個UI子組件(ProvinceComponent、CityComponent、DistrictComponent)
在這里插入圖片描述
完整代碼如下:

ProvinceComponent.ets

import agconnect from '@hw-agconnect/api-ohos';
import "@hw-agconnect/function-ohos";import { ProvinceBean } from '../bean/ProvinceBean'
import { Log } from '../common/Log';@Component
export struct ProvinceComponent {@State mProvinceData: ProvinceBean[] = [];@Consume currentProvince: ProvinceBean;aboutToAppear() {this.callFunction();}build() {Column() {Text('省份').width('100%').height(50).fontSize(20).fontWeight(500).textAlign(TextAlign.Center).border({color: '#e2e2e2',width: { bottom: 1 }})Column() {if (this.mProvinceData.length === 0) {Text('加載中').fontSize(20)} else {List({ space: 10, initialIndex: 0 }) {ForEach(this.mProvinceData, (item: ProvinceBean) => {ListItem() {Text(item.label).width('100%').height(50).fontSize(20).textAlign(TextAlign.Center)}.backgroundColor(this.currentProvince?.code === item.code ? '#c8aaf4fc' : Color.Transparent).onClick(() => {this.currentProvince = item;})}, item => JSON.stringify(item))}.width('100%').height('100%').divider({ strokeWidth: 1, color: "#e2e2e2", startMargin: 5, endMargin: 5 })}}.backgroundColor(Color.White).border({color: '#e2e2e2',width: { right: 0.5 }}).width('100%').layoutWeight(1).justifyContent(FlexAlign.Center)}.height('100%')}callFunction() {agconnect.instance().init(getContext(this));let functionCallable = agconnect.function().wrap("province-query-$latest");let params = {};functionCallable.call(params).then((ret: any) => {Log.info("Functions", "Cloud Function Called, Returned Value: " + JSON.stringify(ret.getValue()));this.mProvinceData = ret.getValue().result;if (this.mProvinceData.length > 0) {this.currentProvince = this.mProvinceData[0];}}).catch((error: any) => {Log.error("Functions", "Error - could not obtain cloud function result. Error Detail: " + JSON.stringify(error));});}
}

CityComponent.ets

import agconnect from '@hw-agconnect/api-ohos';
import { CityBean } from '../bean/CityBean';
import { ProvinceBean } from '../bean/ProvinceBean';
import { Log } from '../common/Log';@Component
export struct CityComponent {@State mTip: string = ''@State mCityData: CityBean[] = [];@Consume @Watch('onProvinceChange') currentProvince: ProvinceBean;@Consume currentCity: CityBean;build() {Column() {Text('城市').width('100%').height(50).fontSize(20).fontWeight(500).textAlign(TextAlign.Center).border({color: '#e2e2e2',width: { bottom: 1 }})Column() {if (this.mCityData.length === 0) {Text(this.mTip).fontSize(20)} else {List({ space: 10, initialIndex: 0 }) {ForEach(this.mCityData, (item: CityBean) => {ListItem() {Text(item.label).width('100%').height(50).fontSize(20).textAlign(TextAlign.Center)}.backgroundColor(this.currentCity?.code === item.code ? '#c8aaf4fc' : Color.Transparent).onClick(() => {this.currentCity = item;})}, item => JSON.stringify(item))}.width('100%').height('100%').divider({ strokeWidth: 1, color: "#e2e2e2", startMargin: 5, endMargin: 5 })}}.backgroundColor(Color.White).border({color: '#e2e2e2',width: { right: 0.5 }}).width('100%').layoutWeight(1).justifyContent(FlexAlign.Center)}.height('100%')}onProvinceChange() {Log.info("Functions", "onProvinceChange");this.mCityData.splice(0, this.mCityData.length);if (this.currentProvince) {this.mTip = '加載中';this.callFunction(this.currentProvince.code);}}callFunction(provinceCode: string) {agconnect.instance().init(getContext(this));let functionCallable = agconnect.function().wrap("city-query-$latest");let params = { "code": provinceCode };Log.info("Functions", "Cloud Function Called, body: " + JSON.stringify(params));functionCallable.call(params).then((ret: any) => {Log.info("Functions", "Cloud Function Called, Returned Value: " + JSON.stringify(ret.getValue()));this.mCityData = ret.getValue().result;if (this.mCityData.length > 0) {this.currentCity = this.mCityData[0];}}).catch((error: any) => {Log.error("Functions", "Error - could not obtain cloud function result. Error Detail: " + JSON.stringify(error));});}
}

DistrictComponent.ets

import agconnect from '@hw-agconnect/api-ohos';
import { CityBean } from '../bean/CityBean';
import { DistrictBean } from '../bean/DistrictBean';
import { Log } from '../common/Log';
import { ProvinceBean } from '../bean/ProvinceBean';@Component
export struct DistrictComponent {@State mTip: string = ''@State mDistrictData: DistrictBean[] = [];@Consume @Watch('onProvinceChange') currentProvince: ProvinceBean;@Consume @Watch('onCityChange') currentCity: CityBean;@Consume currentDistrict: DistrictBean;build() {Column() {Text('區縣').width('100%').height(50).fontSize(20).fontWeight(500).textAlign(TextAlign.Center).border({color: '#e2e2e2',width: { bottom: 1 }})Column() {if (this.mDistrictData.length === 0) {Text(this.mTip).fontSize(20)} else {List({ space: 10, initialIndex: 0 }) {ForEach(this.mDistrictData, (item: DistrictBean) => {ListItem() {Text(item.label).width('100%').height(50).fontSize(20).textAlign(TextAlign.Center)}.backgroundColor(this.currentDistrict?.code === item.code ? '#c8aaf4fc' : Color.Transparent).onClick(() => {this.currentDistrict = item;})}, item => JSON.stringify(item))}.width('100%').height('100%').divider({ strokeWidth: 1, color: "#e2e2e2", startMargin: 5, endMargin: 5 })}}.backgroundColor(Color.White).border({color: '#e2e2e2',width: { right: 0.5 }}).width('100%').layoutWeight(1).justifyContent(FlexAlign.Center)}.height('100%')}onProvinceChange() {this.mDistrictData.splice(0, this.mDistrictData.length);}onCityChange() {Log.info("Functions", "onCityChange");this.mDistrictData.splice(0, this.mDistrictData.length);if (this.currentCity) {this.mTip = '加載中';this.callFunction(this.currentCity.code);}}callFunction(cityCode: string) {agconnect.instance().init(getContext(this));let functionCallable = agconnect.function().wrap("districts-query-$latest");let params = { "code": cityCode };Log.info("Functions", "Cloud Function Called, body: " + JSON.stringify(params));functionCallable.call(params).then((ret: any) => {Log.info("Functions", "Cloud Function Called, Returned Value: " + JSON.stringify(ret.getValue()));this.mDistrictData = ret.getValue().result;if (this.mDistrictData.length > 0) {this.currentDistrict = this.mDistrictData[0];}}).catch((error: any) => {Log.error("Functions", "Error - could not obtain cloud function result. Error Detail: " + JSON.stringify(error));});}
}

三個UI子組件的UI樣式基本一致,功能也是基本一致,大家也可以進行代碼封裝重構,基于通用模型抽取成一個模板組件,這里只演示功能,就不過多贅述。在這里我們就拿城市列表視圖 CityComponent.ets來進行代碼的講解。

1、首先我們定義了四個狀態變量。

  @State mTip: string = ''@State mCityData: CityBean[] = [];@Consume @Watch('onProvinceChange') currentProvince: ProvinceBean;@Consume currentCity: CityBean;
  • mTip 用于顯示加載中提示語
  • mCityData 是城市列表的數據源
  • currentProvince 是當前選中的省份信息對象(我們基于該對象的省份編碼來查詢城市列表)。
  • currentCity 是記錄當前選中的城市。

這里currentProvince 、currentCity 使用**@Consume裝飾**,用于跟頁面中 @Provide裝飾 的狀態變量(currentProvince 、currentCity)做雙向狀態同步,這樣Page頁面可以拿到當前選中的省份、選中的城市的數據,其他的子組件之間也可以進行數據共享。

currentProvince 同時還用了 @Watch(‘onProvinceChange’)裝飾,因為城市列表視圖 CityComponent需要實時監聽切換省份的事件,來動態調用云函數接口獲取對應省份的城市數據,因此這里使用@Watch對currentProvince數據進行觀察,如果省份視圖子組件中選中的省份有所改變,onProvinceChange方法將會接收到回調。

2、build 方法

UI視圖繪制這里,我們根據城市數據源的數據情況,如果是沒數據,就顯示mTip ,如果mCityData 有數據,就使用一個列表進行數據展示

2、onProvinceChange方法

onProvinceChange() {Log.info("Functions", "onProvinceChange");this.mCityData.splice(0, this.mCityData.length);if (this.currentProvince) {this.mTip = '加載中';this.callFunction(this.currentProvince.code);}}

當選中的省份數據有變動時,onProvinceChange會被觸發,我們在該方法中將mCityData 數據源清空,給mTip 設置一個等待提示語,然后調用callFunction 方法請求云函數根據省份編碼查詢城市列表數據。因為currentProvince 是跟Page頁面和省份子組件是進行數據雙向同步的,因此onProvinceChange觸發的時候this.currentProvince.code 也是能拿到最新的切換后的省份編碼。

3、callFunction方法
這里我們重點講下這個方法,這關系到云函數的調用。

 callFunction(provinceCode: string) {agconnect.instance().init(getContext(this));let functionCallable = agconnect.function().wrap("city-query-$latest");let params = { "code": provinceCode };Log.info("Functions", "Cloud Function Called, body: " + JSON.stringify(params));functionCallable.call(params).then((ret: any) => {Log.info("Functions", "Cloud Function Called, Returned Value: " + JSON.stringify(ret.getValue()));this.mCityData = ret.getValue().result;if (this.mCityData.length > 0) {this.currentCity = this.mCityData[0];}}).catch((error: any) => {Log.error("Functions", "Error - could not obtain cloud function result. Error Detail: " + JSON.stringify(error));});}
  • 拿到agconnect實例并進行初始化
  • 通過 agconnect.function().wrap(“city-query-$latest”) 拿到云函數對象控制器,這里具體要調用哪一個云函數,在wrap方法中采用“云函數名稱-版本號” 定義,latest 是最新版本。
  • 使用functionCallable.call(params)觸發請求,params是body,數據類型是JSON對象
  • 使用then異步獲取返回的數據,通過ret.getValue()獲取數據
  • 使用catch處理異常錯誤情況

三個UI視圖子組件開發完畢,下面我們創建個Page頁面將三個子組件整合起來顯示。

創建頁面UI視圖Page文件

1、打開DevEco Studio,在"Application-> entry -> src -> main -> ets -> pages"目錄下新建一個"AreaPage.ets"文件來實現省市地區聯動地址選擇器功能的頁面。
在這里插入圖片描述
2、配置頁面路由
由于模板已經創建了一個main_pages.json文件進行統一的頁面管理,所以我們需要將新建的頁面注冊在"Application-> entry -> src -> main -> resources -> base ->profile -> main_pages.json"文件中。
3、 在EntryAbility.ts 類中onWindowStageCreate 方法中, 將

windowStage.loadContent('pages/Index', (err, data) => {}

中的第一個參數,修改為’pages/AreaPage’

windowStage.loadContent('pages/AreaPage', (err, data) => {}

4、在AreaPage界面放三個控件:一個省份視圖子組件顯示省份列表,一個城市視圖子組件顯示城市列表,并與選擇的省份進行數據聯動,一個區縣視圖子組件顯示區縣列表,并與選擇的城市進行數據聯動,完整示例代碼如下。

import { CityBean } from '../bean/CityBean'
import { DistrictBean } from '../bean/DistrictBean'
import { ProvinceBean } from '../bean/ProvinceBean'
import { CityComponent } from '../component/CityComponent'
import { DistrictComponent } from '../component/DistrictComponent'
import { ProvinceComponent } from '../component/ProvinceComponent'@Entry
@Component
export struct AreaPage {@Provide currentProvince: ProvinceBean = null;@Provide currentCity: CityBean = null;@Provide currentDistrict: DistrictBean = null;build() {Row() {ProvinceComponent().width('30%')CityComponent().width('35%')DistrictComponent().width('35%')}.height('100%')}
}

這里我們定義了三個狀態變量,存儲當前選擇的省份、選擇的城市、選擇的區縣這三個對象,并使用@Provide裝飾器,這樣@Provide裝飾的狀態變量與子組件的@Consume裝飾器裝飾的同名狀態變量,會實現一個數據狀態雙向綁定。具體如下圖:

AreaPage-currentProvince分別與ProvinceComponent-currentProvince 、 CityComponent-currentProvince 直接建立數據狀態雙向綁定,ProvinceComponent-currentProvince 與CityComponent-currentProvince 間接建立數據狀態雙向綁定。
在這里插入圖片描述
這樣,我們這個省市區縣聯動的地址選擇器功能就完成了。

打包測試

1.DevEco Studio菜單選擇“File -> Project Structure”,在“Project Structure”界面導航選擇“Project”,選擇“Signing Configs”頁簽。

2.勾選“Automatically generate signature” ,自動簽名完成后點擊“OK”。
在這里插入圖片描述
3.將應用服務推送到支持API 9及以上版本的手機。

4.顯示效果如下:
在這里插入圖片描述
5.控制臺日志如下:
在這里插入圖片描述

總結

通過《【鴻蒙應用ArkTS開發系列】- 云開發入門實戰三 實現省市地區三級聯動地址選擇器組件》上下篇這兩篇文章, 你應該已經成功地掌握使用HarmonyOS云開發能力開發了一個應用,學會如何使用云數據庫、云函數,實現端、云的交互。

感謝閱讀,后續有疑問或者其他問題,可以在評論區留言交流。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166188.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166188.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166188.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

三次輸錯密碼后,系統是怎么做到不讓我繼續嘗試的?

1故事背景 忘記密碼這件事,相信絕大多數人都遇到過,輸一次錯一次,錯到幾次以上,就不允許你繼續嘗試了。 但當你嘗試重置密碼,又發現新密碼不能和原密碼重復: 圖片 相信此刻心情只能用一張圖形容&#xf…

Mobaxterm 使用lrzsz傳輸文件(rz/sz)

Mobaxterm 使用lrzsz傳輸文件報錯 1. 現象 最近從xshell切換到Mobaxterm其他一切正常,就是使用rz傳輸文件時會出現錯誤,比較苦惱. 會出現以下錯誤 [rootcentos7 rpmbuild]# rz ?CCCCCCCCCCC23be50ive.**B0100000023be502. 解決方法 去官網(https://mobaxterm.mobatek.net…

2021年03月 Scratch(三級)真題解析#中國電子學會#全國青少年軟件編程等級考試

Scratch等級考試(1~4級)全部真題?點這里 一、單選題(共25題,每題2分,共50分) 第1題 在《采礦》游戲中,當角色撿到黃金時財富值加1分,撿到鉆石時財富值加2分,下面哪個程序實現這個功能? A: B: C: D: 答案:D A將變量值固定,BC為雙重判斷

練習七-在Verilog中使用任務task

在Verilog中使用任務task 1,任務目的2,RTL代碼,交換3,測試代碼4,波形顯示 1,任務目的 (1)掌握任務在verilog模塊設計中的應用; (2)學會在電平敏感…

Android Studio記錄一個錯誤:Execution failed for task ‘:app:lintVitalRelease‘.

Android出現Execution failed for task :app:lintVitalRelease.> Lint found fatal errors while assembling a release target. Execution failed for task :app:lintVitalRelease解決方法 Execution failed for task ‘:app:lintVitalRelease’ build project 可以正常執…

〖大前端 - 基礎入門三大核心之JS篇?〗- DOM事件對象及它的屬性

說明:該文屬于 大前端全棧架構白寶書專欄,目前階段免費,如需要項目實戰或者是體系化資源,文末名片加V!作者:不渴望力量的哈士奇(哈哥),十余年工作經驗, 從事過全棧研發、產品經理等工作&#xf…

進程已結束,退出代碼-1073741571 (0xC00000FD)

今天遇到了一個很邪門的問題,沒有報錯,只是提示“進程已結束,退出代碼-1073741571 (0xC00000FD)”。后來查資料說是棧溢出。 出問題的應該是上面這段代碼。 這里我想把一個128*128的矩陣進行剪枝操作。 傳入的128*128的矩陣太大了,兩組for循…

介紹GLFW庫和OpenGL和GLEW庫三者之間的關系

具體來說,OpenGL是一個開放的圖形庫,它規定了每個函數應該如何執行,以及它們的輸出值,但沒有具體實現。它提供了渲染2D和3D圖形的標準或規范。 GLEW,全稱OpenGL Extension Wrangler Library,是一個用于管理…

【Flink】狀態管理

目錄 1、狀態概述 1.1 無狀態算子 1.2 有狀態算子 2、狀態分類 ?編輯 2.1 算子狀態 2.1.1 列表狀態(ListState) 2.1.2 聯合列表狀態(UnionListState) 2.1.3 廣播狀態(BroadcastState) 2.2 按鍵分…

Redis Transaction事務

Redis 事務的目的是方便用戶一次執行多個命令。執行 Redis 事務可分為三個階段: 開始事務命令入隊執行事務 Redis事務特性 Redis 事務具有兩個重要特性: 1) 單獨的隔離操作 事務中的所有命令都會被序列化,它們將按照順序執行&#xff0c…

圖像標記上線,描點信息盡在掌握丨三疊云

圖像標記 路徑 表單設計 >> 組件 >> 增強組件 功能簡介 「圖像標記」字段是「增強字段」類型字段。用戶通過上傳圖片的方式構建一個背景圖片,并在構建的圖片背景上添加描點信息。搭配「儀表盤」中的「圖像軌跡」,可繪制出相應的數據軌跡…

界面組件DevExpress Reporting v23.1 - Web報表設計器功能升級

DevExpress Reporting是.NET Framework下功能完善的報表平臺,它附帶了易于使用的Visual Studio報表設計器和豐富的報表控件集,包括數據透視表、圖表,因此您可以構建無與倫比、信息清晰的報表 界面組件DevExpress Reporting v23.1已經發布一段…

基于JavaWeb+SSM+Vue微信閱讀小程序的設計和實現

基于JavaWebSSMVue微信閱讀小程序的設計和實現 源碼獲取入口Lun文目錄前言主要技術系統設計功能截圖訂閱經典源碼專欄[Java 源碼獲取 源碼獲取入口 Lun文目錄 第1章 緒論 1 1.1 課題背景 1 1.2 課題意義 1 1.3 研究內容 1 第2章 開發環境與技術 3 2.1 MYSQL數據庫 3 2.2 JSP技…

2016年8月15日 Go生態洞察:Go 1.7版本發布

🌷🍁 博主貓頭虎(🐅🐾)帶您 Go to New World?🍁 🦄 博客首頁——🐅🐾貓頭虎的博客🎐 🐳 《面試題大全專欄》 🦕 文章圖文…

解決traefik/nginx-ingress-controller配置正確的情況訪問域名仍然報錯: Connection Refused的問題

最近碰到一個很奇怪的問題: traefik/nginx-ingress-controller配置正確,但是訪問ingress配置的host域名就是死活報錯: Connection Refused 這樣怎么也找不到原因,然后一咬牙直接在其中一臺節點yum安裝nginx, 通過直接反向代理的方…

微信小程序開發資源匯總

本文收集了微信小程序開發過程中會使用到的資料、問題以及第三方組件庫。本文不是一篇關于如何學習微信小程序的入門指南,也非參考手冊,只是一些資料的整理。 本倉庫中的資料整理自網絡,也有一些來自網友的推薦。 官方文檔 小程序設計指南…

UE5 UI教程學習筆記

參考資料:https://item.taobao.com/item.htm?spma21n57.1.0.0.2b4f523cAV5i43&id716635137219&ns1&abbucket15#detail 基礎工程:https://download.csdn.net/download/qq_17523181/88559312 1. 介紹 工程素材 2. 創建Widget UE5 UI系統的…

那些被玩爛了的設計模式

單例模式 單例模式是指一個類在一個進程中只有一個實例對象(但也不一定,比如Spring中的Bean的單例是指在一個容器中是單例的) 單例模式創建分為餓漢式和懶漢式,總共大概有8種寫法。但是在開源項目中使用最多的主要有兩種寫法&am…

electron實現截圖的功能

Electron是一種跨平臺的桌面應用程序開發框架,可以使用HTML、CSS和JavaScript等Web技術構建桌面應用程序。下面是一種使用Electron實現截圖的簡單方法: 安裝Electron和截圖庫 首先,需要安裝Electron和一個截圖庫,例如electron-sc…

替換jar文件中的jar文件中的class

文件格式 testjar.jar在ruoyi.jar中。 AssetServiceImpl.class在testjar.jar 查找testjar.jar路徑 jar -tvf ruoyi.jar | grep testjar.jar 解析testjar.jar jar -xvf ruoyi.jar BOOT-INF/lib/testjar.jar 查找class文件路徑 jar -tvf testjar.jar | grep AssetServiceImp…