鸿蒙学习笔记
- 基础组件的使用
- 配置文件
- 应用入口
- 路由的使用
- 组件中的数据同步
- 网络请求
- 本地数据保存
TypeScript
基础语法
let msg:string = 'hello world'
let age:number = 21
let finished:boolean = true
let a:any = 'jack'
a = 21
let u:string|number|boolean = 'rose'
u = 18
条件控制
let num:number = 21
if(num %2 === 0) {
console.log(num+'是偶数')
}
else {
console.log(num+"是奇数")
}
let grade:string = 'A'
swithc(grade) {
case 'A' {
console.log("优秀")
break
}
default {
console.log("一般")
break
}
}
循环
let names = ["J1","J2"]
for(let n of names){
console.log("n:"+n)
}
函数
- 默认参数
- 空参数
- 函数简写方式
function sayHello(name:string?):string {
console.log("name:"+name)
return name
}
function sayHello2(n?:string):string {
let name = n ? n: "test1"
console.log("name:"+name)
return name
}
sayHello("test")
let sayHi = (name:string) => {
console.log("hello,"+name)
}
sayHi("test")
面向对象
enum Msg {
Hi = "hi",
Hello = "Hello"
}
interface A {
say(msg:Msg):void
}
class B implements A {
say(msg:Msg) {
console.log(msg+", I am B")
}
}
let a:A = new B()
a.say(Msg.Hi)
例子2
class Rect {
private w:number
private h:number
constructor(w:number,h:number){
this.w = w
this.h = h
}
public area():number {
return this.w* this.h
}
}
class Square extends Rect {
constructor(s:number){
super(s,s)
}
}
let s = new Square(10)
console.log("area:"+s.area())
模块
- export
- import .. from 'file'
import {Header} from '../common/components/CommonComponents'
@Component
export struct Header{
private title: ResourceStr
@State params: any = router.getParams()
build(){
// 标题部分
Row({space: 5}){
Image($r('app.media.ic_public_back'))
.width(30)
.onClick(() => {
})
if(this.params && this.title){
Text(this.params.id + '.' + this.title)
.fontSize(28)
.fontWeight(FontWeight.Bold)
}
Blank()
Image($r('app.media.ic_public_refresh'))
.width(30)
}
.width('98%')
.height(30)
}
}
组件使用
Image组件的使用
Image("https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/96c2cb5ead8247e09bf1a857982bc108~tplv-k3u1fbpfcp-watermark.image?")
.width(100)
.height(100)
Image($r('app.media.icon'))
.width(200)
.width(200)
.padding(10)
.interpolation(ImageInterpolation.High)
module.json5
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
],
- 网络图片的显示
- 本地图片的显示
- 权限的设置
Text组件的使用
Text($r('app.string.width_label'))
.fontSize(50)
.fontWeight(FontWeight.Bold)
// .fontColor(this.color)
.onHover(()=> {
this.message += 2
// this.color = "#fff"
})
.onClick(()=> this.message += 1)
- 资源的读取
- 多语言的实现
布局的学习
- 交叉轴
- 主轴
- margin
- padding
循环控制
- forEach
- 可以多条重用
List
- List
- ListItem
- 可以滑动
List(){
ForEach(this.items,(item:Item2)=>{
ListItem() {
Row() {
Image($r('app.media.icon'))
.width(98)
.height(98)
// .width(198)
.padding(8)
.interpolation(ImageInterpolation.High)
Column(){
Text(item.name)
Text(item.price.toFixed(0))
.padding({top:8})
}
.justifyContent(FlexAlign.Start)
.alignItems(HorizontalAlign.Start)
}
.justifyContent(FlexAlign.Start)
.backgroundColor("#fff")
.width("90%")
.height(118)
.margin(14)
.borderRadius(18)
.padding(16)
}
}
)
}
}
自定义组件
- export
- import .. from ..
- 可以增加重用
- @Builder
- 抽取代码,方便业务组件的重用
- @Styles
- 样式的抽取
- 所有组件的公共样式
- @Extend
- 提取某个组件的样式
- build函数中只允许有一个根
@Styles fillScreen(){
.width('100%')
.height('100%')
.backgroundColor('#EFEFEF')
.padding(20)
}
@Extend(Text) function finishedTask(){
.decoration({type:TextDecorationType.LineThrough})
.fontColor('#B1B2B1')
}
@Builder function ItemCard2(item:Item2) {
Row() {
Image($r('app.media.icon'))
.width(98)
.height(98)
// .width(198)
.padding(8)
.interpolation(ImageInterpolation.High)
Column(){
Text(item.name)
Text(item.price.toFixed(0))
.padding({top:8})
}
.justifyContent(FlexAlign.Start)
.alignItems(HorizontalAlign.Start)
}
.justifyContent(FlexAlign.Start)
.backgroundColor("#fff")
.width("90%")
.height(118)
.margin(14)
.borderRadius(18)
.padding(16)
}
路由
- router
- 系统提供
- 在main_pages.json中定义可用的page
- 跳转时使用router.pushurl传入跳转的page来跳转
- 可以传入url
- 可以传入参数
- 可以传入模式
- 通过router.back来返回
import router from '@ohos.router'
import RouterInfo from '../viewmodel/RouterInfo'
@Component
export default struct RouterItem{
r: RouterInfo
i: number
@Consume fontSize: number
build(){
Row(){
Text(this.i + '.')
.fontSize(this.fontSize)
.fontColor(Color.White)
Blank()
Text(this.r.title)
.fontSize(this.fontSize)
.fontColor(Color.White)
}
.width('90%')
.padding(12)
.backgroundColor('#38f')
.borderRadius(20)
.shadow({radius: 6, color: '#4F000000', offsetX: 2, offsetY: 4})
.onClick(() => {
// router跳转
router.pushUrl(
{
url: this.r.url,
params: {id: this.i}
},
router.RouterMode.Single,
err => {
if(err){
console.log(`路由失败,errCode: ${err.code} errMsg:${err.message}`)
}
}
)
})
}
}
状态管理
- @State
- 通过这个来修饰变量以后就会绑定修改
- 这个值变化会影响绑定的ui
- 不能为空
- 不支持any
- 嵌套类型是不能触发变化
- 数组变化是触发变化
- 数组中的对象发生变化是不会触发变化v
- @Entry
- 页面的入口
- @Prop
- 单向同步
- 不能初始化
- 只支持基本类型
- @Link
- 双向同步
- 不能初始化
- 使用$来把地址传入进去
- @Provider @Consume
- 跨组件使用数据,使用@Provider在父组件标记对象
- 在子组件使用@Consume标记的相同变量可以直接使用,不需要传递
- 父组件和子组件名字必须相同
- 函数传递
- this数据的绑定
// 任务类
@Observed
class Task{
static id: number = 1
// 任务名称
name: string = `任务${Task.id++}`
// 任务状态:是否完成
finished: boolean = false
}
// 任务统计信息
class StatInfo {
totalTask: number = 0
finishTask: number = 0
}
@Entry
@Component
struct PropPage {
// 统计信息
@Provide stat: StatInfo = new StatInfo()
build() {
Column({space: 10}){
Header()
// 1.任务进度卡片
TaskStatistics()
// 2.任务列表
TaskList()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F2F3')
}
}
@Component
struct TaskStatistics {
@Consume stat: StatInfo
build() {
Row(){
Text('任务进度:')
.fontSize(30)
.fontWeight(FontWeight.Bold)
}
}
.card()
.margin({top: 5, bottom: 10})
.justifyContent(FlexAlign.SpaceEvenly)
}
}
@Component
struct TaskList {
// 总任务数量
@Consume stat: StatInfo
// 任务数组
@State tasks: Task[] = []
handleTaskChange(){
// 1.更新任务总数量
this.stat.totalTask = this.tasks.length
// 2.更新已完成任务数量
this.stat.finishTask = this.tasks.filter(item => item.finished).length
}
build() {
Column(){
// 2.新增任务按钮
Button('新增任务')
.width(200)
.margin({bottom: 10})
.onClick(() => {
// 1.新增任务数据
this.tasks.push(new Task())
// 2.更新任务总数量
this.handleTaskChange()
})
// 3.任务列表
List({space: 10}){
ForEach(
this.tasks,
(item: Task, index) => {
ListItem(){
TaskItem({item: item, onTaskChange: this.handleTaskChange.bind(this)})
}
.swipeAction({end: this.DeleteButton(index)})
}
)
}
.width('100%')
.layoutWeight(1)
.alignListItem(ListItemAlign.Center)
}
}
@Builder DeleteButton(index: number){
Button(){
Image($r('app.media.ic_public_delete_filled'))
.fillColor(Color.White)
.width(20)
}
.width(40)
.height(40)
.type(ButtonType.Circle)
.backgroundColor(Color.Red)
.margin(5)
.onClick(() => {
this.tasks.splice(index, 1)
this.handleTaskChange()
})
}
}
@Component
struct TaskItem {
@ObjectLink item: Task
onTaskChange: () => void
build() {
Row(){
if(this.item.finished){
Text(this.item.name)
.finishedTask()
}else{
Text(this.item.name)
}
Checkbox()
.select(this.item.finished)
.onChange(val => {
// 1.更新当前任务状态
this.item.finished = val
// 2.更新已完成任务数量
this.onTaskChange()
})
}
.justifyContent(FlexAlign.SpaceBetween)
}
}
Stage模型
- entry 入口
- 模块分类
- ability module
- 可以有很多
- 入口只能有一个 为entry,其他的为Feature
- 打包为hap
- library module
- 打包为hsp
- ability module
配置文件
- app.json5
- module.json5
- mainpages.json5
生命周期
入口页面的配置
- main_pages.json5
- EntryAbility.ts
- windowStage.loadContent
页面的生命周期
- aboutToAppear
- aboutToDisappear
- 页面生命周期
- onPageShow
- onBackPress
- onPageHide
- 页面生命周期在组件生命周期内不可用
- 在一个page中启动另外一个Ability
- 拿到content
- 定义want
- 使用startAbility启动
- 在启动的Ability中重写onAcceptWant方法
- 在module。json5中填写配置
使用网络库获取数据
- viewModel中定义访问,使用的是http库
- 在Model中定义对象
- 得到的是Promise方法
- 使用链式回调then和catch来处理返回值
- 使用JSON.parse转化json为对象
- 使用JSON.stringify把对象转为字符串
- 在onEnd方法中处理分页,修改viewModel中的分页值,重新拉取
- 数据合并
getShopListByHttp(): Promise<ShopInfo[]> {
return new Promise((resolve, reject) => {
// 1.创建http的请求对象
let httpRequest = http.createHttp()
// 2.发送请求
httpRequest.request(
`${this.baseURL}/shops?pageNo=${this.pageNo}&pageSize=3`,
{
method: http.RequestMethod.GET
}
)
.then(resp => {
if (resp.responseCode === 200) {
// 查询成功
console.log('testTag', '查询商铺成功!', resp.result)
resolve(JSON.parse(resp.result.toString()))
} else {
console.log('testTag', '查询商铺信息失败!error:', JSON.stringify(resp))
reject('查询商铺失败')
}
})
.catch(error => {
console.log('testTag', '查询商铺信息失败!error:', JSON.stringify(error))
reject('查询商铺失败')
})
})
}
使用第三方库来完成数据
- 安装ohpm
- ohpm/bin/init.bat
- 使用ohpm.bat install @ohos/axio
- ohpackage.json5
import axios from '@ohos/axios'
async getShopListByAxiosAsync(): Promise<ShopInfo[]> {
// 1.发送请求
let resp = await axios.get(
`${this.baseURL}/shops`,
{
params: { pageNo: this.pageNo, pageSize: 3 }
}
)
// 2.处理响应
if (resp.status === 200) {
// 查询成功
console.log('testTag', '查询商铺成功!', JSON.stringify(resp.data))
return resp.data;
}
// 查询失败
console.log('testTag', '查询商铺信息失败!error:', JSON.stringify(resp))
}
数据保存
- async
- await
- 异步转成同步
关系型数据库
- 导入relationalStore
- 拿到relationalStore对象
- 拿到配置,生成relationalStore对象,拿到数据库链接
- 拿到rdbStore以后,就可以执行executeSql了
- 查询
查询
通知
- 引入通知类
- 创建通知请求
- 发布通知
- 取消通知