[完結(jié)14章]鴻蒙系統(tǒng)實(shí)戰(zhàn)短視頻App 從0到1掌握HarmonyOS
網(wǎng)盤(pán)地址:https://pan.baidu.com/s/1KqyO8--FE6LSDoNcVfwLbQ 提取碼:p64r?
騰訊微云下載地址:https://share.weiyun.com/aXaiIMC3 密碼:q5aaj7
HarmonyOS作為全球第三大移動(dòng)應(yīng)用生態(tài),已有諸多公司將鴻蒙開(kāi)發(fā)列入招聘優(yōu)先選項(xiàng),現(xiàn)在入局正當(dāng)時(shí)。但鴻蒙系統(tǒng)涉及頗廣,入門(mén)容易,進(jìn)階難。本課程特邀鴻蒙資深技術(shù)達(dá)人帶你系統(tǒng)學(xué)習(xí)HarmonyOS 組件和API,實(shí)戰(zhàn)HarmonyOS 9大主題核心技術(shù),具備0到1獨(dú)立實(shí)現(xiàn)完整HarmonyOS App實(shí)戰(zhàn)能力,助力移動(dòng)端開(kāi)發(fā)者拓展職業(yè)新邊界。
針對(duì)HarmonyOS開(kāi)發(fā)按不同的角度劃分,可以有不同的分發(fā):
? ? ? ? 1、從宏觀大類上分為三類:1)通用開(kāi)發(fā)(可安裝應(yīng)用app,兼容安卓和鴻蒙)、2)原子化服務(wù)(鴻蒙自己特有的免安裝應(yīng)用服務(wù))、3)智能設(shè)備開(kāi)發(fā)(智慧屏、穿戴設(shè)備,華為最新的手表已經(jīng)支持安裝應(yīng)用了,可以說(shuō)想象無(wú)限,未來(lái)可以當(dāng)做微型手機(jī))。
? ? ? ? 2、如果從開(kāi)發(fā)語(yǔ)言上分:Java、JavaScript(支持傳統(tǒng)js和帶界面的低代碼量開(kāi)發(fā))、eTS(華為自定義的一種聲明式語(yǔ)言,代碼簡(jiǎn)練更符合開(kāi)發(fā)習(xí)慣,華為自己宣傳更貼近自然語(yǔ)義,更高效、簡(jiǎn)潔,跨平臺(tái),粗看代碼非常簡(jiǎn)練、易懂)。
本文適用于 HarmonyOS 應(yīng)用開(kāi)發(fā)的初學(xué)者。編寫(xiě)兩個(gè)簡(jiǎn)單的頁(yè)面,實(shí)現(xiàn)在 第一個(gè)頁(yè)面點(diǎn)擊按鈕跳轉(zhuǎn)到第二個(gè)頁(yè)面,之后還可以通過(guò)跨設(shè)備啟動(dòng)第二個(gè) 頁(yè)面來(lái)初步體驗(yàn) HarmonyOS 的分布式能力。
編寫(xiě)第一個(gè)頁(yè)面 在 Java UI 框架中,提供了兩種編寫(xiě)布局的方式:在 XML 中聲明 UI 布局和 在代碼中創(chuàng)建布局。這兩種方式創(chuàng)建出的布局沒(méi)有本質(zhì)差別,為了熟悉兩種 方式,我們將通過(guò) XML 的方式編寫(xiě)第一個(gè)頁(yè)面,通過(guò)代碼的方式編寫(xiě)第二個(gè) 頁(yè)面。
XML 編寫(xiě)頁(yè)面 1. 在“Project”窗口,打開(kāi)“entry > src > main > resources > base”,右鍵點(diǎn)擊“base”文件夾,選擇“New > Directory”,命名為“l(fā)ayout”。
創(chuàng)建請(qǐng)求實(shí)例
請(qǐng)求攔截:可以攔截每次或某些特定請(qǐng)求 HTTP請(qǐng)求;為請(qǐng)求帶上添加 token
響應(yīng)攔截:判斷錯(cuò)誤狀態(tài)碼, 進(jìn)行相應(yīng)報(bào)錯(cuò)等提示操作;清除過(guò)期 token
封裝常用請(qǐng)求:get、post、delete等等
定義接口方法:封裝調(diào)用后端 api的操作,返回一個(gè) Promise對(duì)象
import axios from 'axios'
const defaultConfig = {
? timeout: 5000,
? baseURL: '/release/'
}
const axiosInstance = axios.create(defaultConfig)
// 添加請(qǐng)求攔截器
axiosInstance.interceptors.request.use(config => {
? return config
}, (err) => {
? // 對(duì)請(qǐng)求錯(cuò)誤做些什么
? return Promise.reject(err)
})
// 請(qǐng)求攔截器,內(nèi)部根據(jù)返回值,重新組裝,統(tǒng)一管理。
axiosInstance.interceptors.response.use(res => {
? console.log('接口詳情:',res)
? return res
})
export default {
? // 封裝get
? httpGet(url: any, params = {}) {
? ? return axiosInstance.get(url, { params }).then(res => res.data).catch()
? },
? // 封裝post
? httpPost(url: any, params = {}) {
? ? return axiosInstance.get(url, { params }).then(res => res.data).catch()
? }
}
如何使用 TS來(lái)改造呢,我們將 Axios請(qǐng)求定義成一個(gè)類,封裝好常用的請(qǐng)求,暴露出去,將一些私有屬性和方法放置在 class內(nèi)部,比如:Axios實(shí)例、請(qǐng)求和相應(yīng)攔截;另外將一些方法暴露出去給外部使用,比如 get和post請(qǐng)求方式
import axios, { AxiosRequestConfig,AxiosResponse } from 'axios'
import { ElMessage } from 'element-plus'
const defaultConfig:AxiosRequestConfig = {
? timeout: 5000,
? baseURL: '/release/'
}
class Http {
? constructor() {
? ? this.httpInterceptorsRequest()
? ? this.httpInterceptorsResponse()
? }
? // 實(shí)例化axios
? private static axiosInstance = axios.create(defaultConfig)
? // 請(qǐng)求攔截
? private httpInterceptorsRequest(): void {
? ? Http.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
? ? ? return config
? ? }, (err:any) => {
? ? ? // 對(duì)請(qǐng)求錯(cuò)誤的處理
? ? ? return Promise.reject(err)
? ? })
? }
? // 響應(yīng)攔截
? private httpInterceptorsResponse(): void {
? ? Http.axiosInstance.interceptors.response.use((res: AxiosResponse) => {
? ? ? // 對(duì)響應(yīng)成功的處理,處理一些接口成功的狀態(tài)碼,比如:2xx范圍內(nèi)的狀態(tài)碼
? ? ? const { data } = res
? ? ? const { success } = data
? ? ? if (success) {
? ? ? ? ElMessage('成功')
? ? ? } else {
? ? ? ? ElMessage('失敗')
? ? ? }
? ? ? return res
? ? }, (err:any) => {
? ? ? // 對(duì)響應(yīng)錯(cuò)誤的處理,處理一些接口失敗所返回的狀態(tài)碼,比如:3XX,4XX,5XX范圍內(nèi)的狀態(tài)碼
? ? ? return Promise.reject(err)
? ? ? ElMessage('服務(wù)器異常')
? ? })
? }
? public httpGet<T>(url: string, params?: T): Promise<T> {
? ? return Http.axiosInstance.get(url, { params }).then(res => res.data).catch()
? }
? public httpPost<T>(url: string, params?: T): Promise<T> {
? ? return Http.axiosInstance.post(url, { params }).then(res => res.data).catch()
? }
}
export const http = new Http()
onsuccess表示打開(kāi)數(shù)據(jù)庫(kù)成功的事件。
onerror表示打開(kāi)數(shù)據(jù)庫(kù)失敗的事件。
onupgradeneeded是數(shù)據(jù)庫(kù)升級(jí)事件,如果版本號(hào)更新,并且大于之前的版本號(hào)則進(jìn)行數(shù)據(jù)庫(kù)升級(jí),該事件回調(diào)里面,會(huì)創(chuàng)建我們所需要的對(duì)象倉(cāng)庫(kù),類似于關(guān)系型數(shù)據(jù)庫(kù)中的表的概念。
export default class DB {
? private dbName: string // 數(shù)據(jù)庫(kù)名稱
? constructor(dbName: string) {
? ? this.dbName = dbName
? }
? // 打開(kāi)數(shù)據(jù)庫(kù)
? public openStore(storeName: string, keyPath: string, indexs?: Array<string>) {
? ? const request = window.indexedDB.open(this.dbName, 2)
? ? request.onsuccess = (event) => {
? ? ? console.log('數(shù)據(jù)庫(kù)打開(kāi)成功')
? ? ? console.log(event)
? ? }
? ? request.onerror = (event) => {
? ? ? console.log('數(shù)據(jù)庫(kù)打開(kāi)失敗')
? ? ? console.log(event)
? ? }
? ? request.onupgradeneeded = (event) => {
? ? ? console.log('數(shù)據(jù)庫(kù)升級(jí)成功')
? ? ? const { result }: any = event.target
? ? ? const store = result.createObjectStore(storeName, { autoIncrement: true, keyPath })
? ? ? if (indexs && indexs.length > 0) {
? ? ? ? indexs.map((v: string) => {
? ? ? ? ? store.createIndex(v, v, { unique: true })
? ? ? ? })
? ? ? }
? ? ? store.transaction.oncomplete = (event: any) => {
? ? ? ? console.log('創(chuàng)建對(duì)象倉(cāng)庫(kù)成功')
? ? ? }
? ? ? console.log(event)
? ? }
? }
}
內(nèi)核層:提供?機(jī)操作系統(tǒng)的基礎(chǔ)能?。HarmonyOS采?多內(nèi)核的系統(tǒng)設(shè)計(jì),基于 Linux內(nèi)核、LiteOS,使?了Linux的微內(nèi)核(使?了Linux的最簡(jiǎn)功 能)
Linux內(nèi)核: ?機(jī)操作系統(tǒng)的內(nèi)核
LiteOS內(nèi)核:智能硬件的內(nèi)核
系統(tǒng)服務(wù)層:HarmonyOS的核?能?集合,這些能?是有系統(tǒng)本身決定的,為我們應(yīng)? 開(kāi)發(fā)提供了服務(wù)調(diào)?功能。系統(tǒng)服務(wù)層提供的能?是可以被我們開(kāi)發(fā)的應(yīng)?進(jìn)?調(diào)?的。
框架層:為HarmonyOS的應(yīng)?開(kāi)發(fā)提供了不同語(yǔ)?程序調(diào)?的接?
updateItem(storeName: string, data: any) {
? ? console.log(this.db)
? ? const store = this.db.transaction([storeName], 'readwrite').objectStore(storeName)
? ? const request = store.put({
? ? ? ...data,
? ? ? updateTIme: new Date().getTime()
? ? })
? ? request.onsuccess = (event: any) => {
? ? ? console.log('數(shù)據(jù)寫(xiě)入成功')
? ? ? console.log(event)
? ? }
? ? request.onerror = (event: any) => {
? ? ? console.log('數(shù)據(jù)寫(xiě)入失敗')
? ? ? console.log(event)
? ? }
}
封裝Mock接口
在 src/api目錄下新建 login模塊的 Mock接口
注冊(cè)接口:userSignApi
代碼片段如下:
// mock接口:用戶注冊(cè)
export async function userSignApi(params: any) {
? const loading = ElLoading.service({
? ? lock: true,
? ? background: 'rgba(0, 0, 0, 0.1)'
? })
? // 是否存在相同手機(jī)號(hào)
? const hasMobile = await new Promise((resolve, reject) => {
? ? airbnb.airbnbDB.getList(storeName).then((res: any) => {
? ? ? setTimeout(() => {
? ? ? ? loading.close()
? ? ? }, 200)
? ? ? res && res.filter((item: any) => {
? ? ? ? if (item.mobile === params.mobile) { // 存在相同手機(jī)號(hào)
? ? ? ? ? resolve(true)
? ? ? ? }
? ? ? })
? ? ? resolve(false)
? ? })
? })
? let result: IResultOr
? if (hasMobile) {
? ? result = await new Promise((resolve, reject) => {
? ? ? resolve({ code: '000001', success: false, message: '數(shù)據(jù)已存在', result: null })
? ? })
? } else {
? ? const obj = { status: 0 }
? ? Object.assign(params, obj)
? ? result = await new Promise((resolve, reject) => {
? ? ? airbnb.airbnbDB.updateItem(storeName, params).then(res => {
? ? ? ? setTimeout(() => {
? ? ? ? ? loading.close()
? ? ? ? }, 200)
? ? ? ? resolve({ code: '000000', success: true, message: '操作成功', result: null })
? ? ? })
? ? })
? }
? return result
}