易得天气
项目采用MVVM模式,关于MVVM模式网上有许多讲解,可以自行去搜索
网络请求封装:
export type NetParamType = string | number | boolean
export default class NetUtils {
private axiosInstance: AxiosInstance = axios.create({
// 设置超时时间
timeout: 15000,
readTimeout: 15000,
connectTimeout: 15000,
headers: {
'Content-Type': 'application/json;charset=utf-8',
'Content-Language': 'zh_CN'
},
});
constructor() {
this.axiosInstance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
return config
})
this.axiosInstance.interceptors.response.use((response: AxiosResponse) => {
return response
})
}
private axiosGet<T>(url: string, axiosConfig: AxiosRequestConfig): Promise<T> {
return this.axiosInstance.get<T, AxiosResponse<T>, null>(url, axiosConfig).then((response: AxiosResponse<T>) => {
const data = response.data
if (!data) {
Promise.reject(new Error('response data is null'))
}
return data
}).catch((error: Error) => {
return Promise.reject(error)
})
}
netGetT<T>(url: string, params?: Map<string, NetParamType>,
headers?: Map<string, string>): Promise<T> {
// 请求参数
const axiosParams = new Map<string, NetParamType>()
if (params && params.size > 0) {
params.forEach((value, key, _) => {
axiosParams[key] = value
})
}
// 请求头
const axiosHeaders = new AxiosHeaders()
if (headers && headers.size > 0) {
headers.forEach((value, key, _) => {
axiosHeaders.set(key, value)
})
}
const axiosRequestConfig: AxiosRequestConfig = {
headers: axiosHeaders,
params: axiosParams
}
return this.axiosGet<T>(url, axiosRequestConfig)
}
netGet<T>(url: string, params?: Map<string, NetParamType>,
headers?: Map<string, string>): Promise<ResultData<T>> {
return this.netGetT<ResultData<T>>(url, params, headers)
}
}
export const netUtils = new NetUtils()
页面状态:
export class ViewState {
// 加载中
static readonly VIEW_STATE_LOADING = 'view_state_loading'
// 成功
static readonly VIEW_STATE_SUCCESS = 'view_state_success'
// 错误
static readonly VIEW_STATE_ERROR = 'view_state_error'
}
ViewModel基类:
@ObservedV2
export default class BaseViewModel {
private _isDestroy = false
@Trace viewState = ViewState.VIEW_STATE_LOADING
@Trace errorMessage = ''
constructor() {
this._isDestroy = false
}
setViewState(viewState: string) {
if (this.viewState != viewState) {
this.viewState = viewState
}
}
setErrorMessage(message: string) {
this.errorMessage = message
}
isSuccess(): boolean {
return ViewState.VIEW_STATE_SUCCESS == this.viewState
}
isLoading(): boolean {
return ViewState.VIEW_STATE_LOADING == this.viewState
}
isError(): boolean {
return ViewState.VIEW_STATE_ERROR == this.viewState
}
get isDestroy(): boolean {
return this._isDestroy;
}
destroy(): void {
this._isDestroy = true;
}
}
首页面的ViewModel:
@ObservedV2
export default class WeatherMainViewModel extends BaseViewModel {
@Trace weatherData = ''
private model = new WeatherMainModel()
async obtainWeatherData(): Promise<void> {
this.setViewState(ViewState.VIEW_STATE_LOADING)
this.model.obtainWeatherData()
.then((weatherData: WeatherData) => {
this.weatherData = JSON.stringify(weatherData)
this.setViewState(ViewState.VIEW_STATE_SUCCESS)
})
.catch((e: Error) => {
this.setErrorMessage(e.message)
this.setViewState(ViewState.VIEW_STATE_ERROR)
})
}
}
首页面Model层:
export default class WeatherMainModel {
async obtainWeatherData(): Promise<WeatherData> {
return netUtils.netGetT<WeatherData>(Api.WEATHER_API, new Map([
['citykey', 101210113],
]))
}
}
首页写法:
@Route({ name: RouterConstants.WEATHER_MAIN_PAGE })
@ComponentV2
export struct WeatherMainPage {
@Local weatherMainVM: WeatherMainViewModel = new WeatherMainViewModel()
async aboutToAppear() {
console.log('WeatherMainPage aboutToAppear')
setTimeout(() => {
this.weatherMainVM.obtainWeatherData()
}, 2000)
}
build() {
NavDestination() {
Column() {
Text(this.getText())
.fontColor(Color.Black)
.fontSize(14)
.height('100%')
}
.width('100%')
.height('100%')
}
.hideTitleBar(true)
.height('100%')
.width('100%')
.onBackPressed(() => {
console.log('WeatherMainPage onBackPressed');
AppUtil.exit()
return true
})
}
getText(): string {
if (this.weatherMainVM.isLoading()) {
return '天气数据加载中...'
} else if (this.weatherMainVM.isError()) {
return this.weatherMainVM.errorMessage
} else {
return this.weatherMainVM.weatherData
}
}
}
效果图: