以下所有代码涉及的源码地址: https://gitee.com/jiangqianghua/harmony-test
点我获取更多it学习资源
@Entry // 入口文件
@Component // 组件
struct Index {
// @State 让普遍变量有状态
@State message: string = 'Hello World111111'
// build 特点
// 1. 根节点只有一个, 根节点必须是容器 2 不能声明本地变量 3 不允许console.info,4 不允许调用没有用@Builder装饰的方法
// 5. 不允许switch,使用if代替, 6 不允许表达式,比如三目运算
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.backgroundColor(Color.Red)
.border({width: 5, color: Color.Black, style: BorderStyle.Dotted})
.margin(10)
.padding(10)
.borderRadius(20)
if (false) Divider()
Button('click me')
// .onClick(() => {this.message = 'click me'})
// .onClick(function(){
// this.message = 'click me'
// }.bind(this))
// .onClick(this.changeMessage)
.onClick(this.changeMessage2.bind(this))
}
.width('100%')
}
.height('100%')
}
changeMessage = () => {
this.message = 'click me'
}
changeMessage2(){
this.message = 'click me'
}
}
@Entry
@Component
struct Page2 {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
this.TextLabel()
TextLabel2()
}
.width('100%')
}
.height('100%')
}
// 内部构建组件函数
@Builder
TextLabel() {
Text(this.message)
.fontSize(30)
.backgroundColor(Color.Red)
.onClick(() => { this.message = 'click me'})
}
}
// 外部构建组件函数, 也可以使用this,但是不建议,使用传参方式
@Builder
function TextLabel2() {
Text(this.message)
.fontSize(30)
.backgroundColor(Color.Red)
.onClick(() => { this.message = 'click me'})
}
@Entry
@Component
struct Page3 {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
// 这种值传递,状态发生变化,组件不会被修改
TextLabel3(this.message)
// 需要引用传递,被$$1接受,状态发生变化,组件会改变,单组件内无法修改该值
// cb 是回调
TextLabel4({message: this.message, cb: (value: string) => {
console.log(value)
}})
Button('click').onClick(() => this.message = 'click')
}
.width('100%')
}
.height('100%')
}
}
// 值传递
@Builder
function TextLabel3(message: string) {
Text(message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
// 引用传递
// $$1 可以任意取
@Builder
function TextLabel4($$1:{message: string, cb:(value: string)=>void}) {
Text($$1.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
$$1.cb('text click')
})
}
// 提取样式
@Entry
@Component
struct Page4 {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message)
.fontSize(20)
.fontWeight(FontWeight.Bold)
.commonStyle()
}
.width('100%')
}
.height('100%')
}
}
// 全局定义样式, 只支持通用属性和事件, 比如 fontColor, 且不支持传参, 可以定义在组件内,也能定义在全局
@Styles
function commonStyle(){
.width(200)
.height(100)
.margin(10)
.padding(10)
.backgroundColor(Color.Red)
.border({width: 5, color: Color.Blue, style: BorderStyle.Solid})
.borderRadius('20.00vp')
}
和@Styles区别
// 扩展组件样式
@Entry
@Component
struct Page5 {
@State message: string = 'Hello World'
@State color: Color = Color.Pink
build() {
Row() {
Column() {
Text(this.message)
.MyText1(this.color, (value) => {
console.log(value)
this.color = Color.Green
} )
}
.width('100%')
}
.height('100%')
}
}
// 可以传参数以及回调函数, 参数是有状态的,会跟着外部变化而变化
@Extend(Text)
function MyText1(color: Color, cb: (value: string) => void ){
.fontSize(20)
.fontColor(color)
.width(200)
.height(100)
.margin(10)
.padding(10)
.backgroundColor(Color.Red)
.border({width: 5, color: Color.Blue, style: BorderStyle.Solid})
.borderRadius('20.00vp')
.onClick(() => {
cb('click')
})
}
@Entry
@Component
struct Page6 {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Button('click')
.width(100)
.height(100)
.onClick(() => {})
// 组件内写法
.stateStyles({
normal: {
.backgroundColor(Color.Green)
},
pressed: {
.backgroundColor(Color.Red)
},
disabled: {
.backgroundColor(Color.Grey)
},
// focused: {
// .backgroundColor(Color.Blue)
// }
})
MyButton2()
}
.width('100%')
}
.height('100%')
}
}
// 外部定义并调用状态样式
@Styles
function normalStyle(){
.backgroundColor(Color.Green)
}
@Styles
function pressedStyle(){
.backgroundColor(Color.Red)
}
@Styles
function disabledStyle(){
.backgroundColor(Color.Grey)
}
@Builder
function MyButton2() {
Button('mybtn')
.width(100)
.height(100)
.stateStyles({
normal: normalStyle,
pressed: pressedStyle,
disabled: disabledStyle
})
}
// forEach
// forEach
@Entry
@Component
struct Pager7 {
@State message: string = 'Hello World'
@State list: string[] = ['商品1', '商品2']
@State list2: Object[] = [{
id:1, title: "商品1"
},{
id:2, title: "商品2"
},{
id:3, title: "商品3"
}]
build() {
Row() {
Column() {
// // forEach 会默认加上key值, 默认是 index + JSON.stringify(item)
// ForEach(this.list,(item: string) => {
// Text(item).fontSize(30)
// })
// ForEach(this.list,(item: string, index: number) => {
// Text(item).fontSize(30)
// // 人为返回一个key, 不推荐, list改变,如果发现index是一样的,不会做改变, 可以使用商品id
// }, (item: string, index: number) => index.toString())
ForEach(this.list2, (item: Object) => {
Text(item['title']).fontSize(30)
})
Button('click').onClick(() => {
// 该方式无法修改成功, 不会引发ui渲染, 使用@ObjectLink解决
// this.list2[0]['title'] = '商品1-修改'
// 另外一个方式
this.list2.splice(0, 1, {
id: 1,
title: '商品1-修改'
})
})
// 使用List组件
if (this.list2.length) {
List() {
ForEach(this.list2, (item: Object) => {
ListItem() {
Text(item['title']).fontSize(30)
}
})
}.height(100).divider({
strokeWidth: 1,
startMargin: 10,
endMargin: 10,
color: Color.Grey
})
} else {
Text('空空如也')
}
}
.width('100%')
}
.height('100%')
}
}
@Entry
@Component
struct Page9 {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
MyComponent({title: this.message, delClick: () => {
console.log('delClick call')
}})
Button('click').onClick(() => {
// 修改后,内部ui不会渲染
this.message = 'click'
})
}
.width('100%')
}
.height('100%')
}
}
@Component
struct MyComponent{
// 自动接受
private title: string ;
public delClick = (event: ClickEvent) => {
}
build(){
Row(){
Text(this.title)
Button('delClick').onClick((event: ClickEvent) => this.delClick(event))
}
}
}
ForEach(this.list.filter(item=>item.includes(this.value)), (item) => {
Text(item).fontSize(30)
})
@Entry
@Component
struct Page9 {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
MyComponent({title: this.message, delClick: () => {
console.log('delClick call')
}})
Button('click').onClick(() => {
// 修改后,内部ui不会渲染
this.message = 'click'
})
}
.width('100%')
}
.height('100%')
}
}
@Component
struct MyComponent{
// 自动接受
@Prop title: string ;
public delClick = (event: ClickEvent) => {
}
build(){
Row(){
Text(this.title)
Button('delClick').onClick((event: ClickEvent) => this.delClick(event))
}
}
}
@Entry
@Component
struct Page_Link {
@State message: string = 'Hello World'
build() {
Row() {
Column() {
Text(this.message).fontColor(Color.Red)
// $message 表示传this.message的引用
MyComponent2({title: $message})
Button('click').onClick(() => {
// 修改后,内部ui不会渲染
this.message = 'click'
})
}
.width('100%')
}
.height('100%')
}
}
@Component
struct MyComponent2{
// 自动接受
@Link title: string ;
build(){
Row(){
Text(this.title)
// 也会改变父类的值
Button('change').onClick((event: ClickEvent) => this.title = 'change')
}
}
}
// @link 修饰对象形式
@Entry
@Component
struct Page_ObjectLink {
@State message: string = 'Hello World'
@State person: Person = new Person('jiang')
build() {
Row() {
Column() {
ShowPerson({ person: $person, cb: () => {
console.log(this.person.name)
}})
}
.width('100%')
}
.height('100%')
}
}
class Person {
name: string
constructor(name: string) {
this.name = name
}
}
@Component
struct ShowPerson{
@Link person: Person;
private cb: () => void;
build(){
Row(){
Text(this.person.name)
Button('change').onClick(() => {
this.person.name = 'change'
this.cb()
})
}
}
}
@Entry
@Component
struct Page_ObjectLink {
@State message: string = 'Hello World'
// 通过@Observed 必须通过new形式生成对象,否则无法监听
@State list: Array<Person> = [new Person('jiang'), new Person('hua')]
build() {
Row() {
Column() {
ForEach(this.list, (item, index) => {
ShowPerson({person: item, cb: () => {
}})
})
}
.width('100%')
}
.height('100%')
}
}
@Observed
class Person {
name: string
constructor(name: string) {
this.name = name
}
}
@Component
struct ShowPerson{
@ObjectLink person: Person;
private cb: () => void;
build(){
Row(){
Text(this.person.name)
Button('change').onClick(() => {
this.person.name = this.person.name + ' change'
this.cb()
})
}
}
}
@Entry
@Component
struct Page_provide {
@Provide('msgkey') message: string = 'Hello World'
build() {
Row() {
Column() {
Text('root')
Parent1()
}
.width('100%')
}
.height('100%')
}
}
@Component
struct Parent1{
@Consume('msgkey') msg: string;
build(){
Column(){
Text('parent-' + this.msg)
Child1()
}
}
}
@Component
struct Child1{
@Consume('msgkey') msg1: string;
build(){
Row(){
Text('child-' + this.msg1)
// 改动,会触发全部所有地方更新
Button('click').onClick(() => this.msg1 = 'change')
}
}
}
@Entry
@Component
struct Page_watch {
@State type: number = 1
build() {
Row() {
Column() {
Row(){
Button('衣服').onClick(() => this.type = 1)
Button('鞋子').onClick(() => this.type = 2)
}
ShowShop({ type: this.type })
}
.width('100%')
}
.height('100%')
}
}
@Component
struct ShowShop{
@Prop @Watch('typeChange') type: number
build(){
Column(){
Text('当前展示的是' + this.type)
}
}
typeChange(){
// 可以监听type变化,然后加载数据
console.log(this.type.toString())
}
}
let storage = new LocalStorage({
name: 'jiang'
})
@Entry(storage)
@Component
struct Page_Cinema {
@State message: string = 'Hello World'
// 在当前页面修改会触发当前ui同步
@LocalStorageProp('name') myname: string = '';
build() {
Row() {
Column() {
Text(this.myname)
.fontSize(50)
.fontWeight(FontWeight.Bold).onClick(() => {
// 以下两种写法,展现形式一样,但是处理过程不一样
// 只会改变当前的值,child不会跟着边,也不会改变 storage的值
// this.myname = 'change'
// 会改变和storage相关的所有值,包含当前的值和child值
storage.set('name', 'change1')
console.log(storage.get('name'))
})
Child2()
}
.width('100%')
}
.height('100%')
}
}
@Component
struct Child2{
@LocalStorageProp('name') myname1: string = ''
build(){
Column(){
Text(this.myname1).onClick(() => {
// 只会改变当前页面的
this.myname1 = 'change2'
})
}
}
}
let storage = new LocalStorage({
name: 'jiang'
})
@Entry(storage)
@Component
struct Page_Cinema {
@State message: string = 'Hello World'
// 在当前页面修改会触发当前ui同步
@LocalStorageLink('name') myname: string = '';
build() {
Row() {
Column() {
Text(this.myname)
.fontSize(50)
.fontWeight(FontWeight.Bold).onClick(() => {
// 以下两种写法等效
this.myname = 'change'
// storage.set('name', 'change1')
console.log(storage.get('name'))
})
Child2()
}
.width('100%')
}
.height('100%')
}
}
@Component
struct Child2{
@LocalStorageLink('name') myname1: string = ''
build(){
Column(){
Text(this.myname1).onClick(() => {
// 也会改变storage的值
this.myname1 = 'change2'
})
}
}
}
EntryAbility.ts
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
storage = new LocalStorage({name: '北京'})
....
onWindowStageCreate(windowStage: window.WindowStage) {
...
windowStage.loadContent('pages/Page_Cinema', this.storage, (err, data) => {
...
});
}
}
Page_Cinema.etx
import router from '@ohos.router';
let storage = LocalStorage.GetShared()
@Entry(storage)
@Component
struct Page_Cinema {
@State message: string = 'Hello World'
// 在当前页面修改会触发当前ui同步
@LocalStorageLink('name') myname: string = '';
build() {
Row() {
Column() {
Text(this.myname)
.fontSize(50)
.fontWeight(FontWeight.Bold).onClick(() => {
// 以下两种写法等效
this.myname = 'change'
// storage.set('name', 'change1')
console.log(storage.get('name'))
})
Child2()
Button('跳转到city').onClick(() => {
router.pushUrl({
url: "pages/Page_City"
})
})
}
.width('100%')
}
.height('100%')
}
}
@Component
struct Child2{
@LocalStorageLink('name') myname1: string = ''
build(){
Column(){
Text(this.myname1).onClick(() => {
// 也会改变storage的值
this.myname1 = 'change2'
})
}
}
}
Page_City.etc
import router from '@ohos.router'
let storage = LocalStorage.GetShared()
@Entry(storage)
@Component
struct Page_City {
@State message: string = 'City'
@LocalStorageLink('name') cityName: string = ''
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Button('返回').onClick(() => {
this.cityName = '南昌'
router.back()
})
}
.width('100%')
}
.height('100%')
}
}
// 创建全局storage,在任何地方都可以创建
AppStorage.SetOrCreate('cityName', '北京')
// 使用的页面使用
@StorageProp('cityName') cityName: string = '';
@StorageLink('cityName') cityName: string = '';
// ui显示
Text(this.cityName)
// 修改
this.cityName = '上海'
AppStorage.Set('cityName', '上海')
// 存储数据
PersistentStorage.PersistProp('cityName', '北京')
// 使用方式和AppStoreage一致
// 使用的页面使用
@StorageProp('cityName') cityName: string = '';
@StorageLink('cityName') cityName: string = '';
// ui显示
Text(this.cityName)
// 修改
this.cityName = '上海'
@Entry
@Component
struct Page_BuilderParam {
@State message: string = 'Hello World'
@Builder
left(){
Row(){
Button('left')
}
}
@Builder
right(){
Row(){
Button('right')
}
}
build() {
Row() {
Column() {
R_NavBar({left: this.left, right: this.right})
// 尾随闭包写法,该方式适合只有一个BuilderParam参数
MyCom1(){
Text('aaaa')
}
}
.width('100%')
}
.height('100%')
}
}
@Component
struct R_NavBar{
@BuilderParam left:()=>void;
@BuilderParam right:()=>void;
build(){
Row(){
this.left()
Text('title')
this.right()
}.justifyContent(FlexAlign.SpaceBetween).width('100%')
}
}
@Component
struct MyCom1{
@BuilderParam comp:() => void;
build(){
Row(){
this.comp()
}
}
}
// A页面
router.pushUrl({
url: "pages/B",
params: {
name: 'jiang'
}
})
// B页面接受
aboutToAppear(){
const params = router.getParams();
console.log('aboutToAppear', JSON.stringify(params))
}
// B页面返回
try {
router.showAlertBeforeBackPage({
message: '你确定要离开吗?'
})
} catch (e) {
}
router.back({
url: 'pages/Page_Cinema',
params: {
id: '1'
}
})
// A页面接受
onPageShow(){
let params = router.getParams();
console.log(JSON.stringify(params))
}
// A Ability
private context = getContext(this) as common.UIAbilityContext;
let want = {
deviceId: '',
bundleName: getContext(this.context).applicationInfo.name,
abilityName: 'BAbility', // module.json5 配置好的名字
parameters: {
info: 'hello'
}
this.context.startAbility(want);
}
// BAbility.ets
onCreate(want, launchParam) {
console.log(want?.parameters?.info)
}
import http from '@ohos.net.http'
@Entry
@Component
struct Page_http {
@State message: string = 'Hello World'
private httpRequest = http.createHttp();
build() {
Row() {
Column() {
Button('http').onClick(() => {
this.httpRequest.request("https:///www.baidu.com",
{
method: http.RequestMethod.GET, //默认是Get,
connectTimeout: 60000,
readTimeout: 60000,
header: {
// 'Content-Type': 'application/json',
// 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
}, (err, data) => {
if (!err) {
console.log(JSON.stringify(data.result))
}
});
// 可以中断
this.httpRequest.destroy()
})
}
.width('100%')
}
.height('100%')
}
}
import dataPreferences from '@ohos.data.preferences'
...
// 入口用 this.context, 页面用 getContext(this)
dataPreferences.getPreferences(this.context, 'mystore', (err, preferences) => {
if (err) {
console.error(`Failed to get Preferences, Code ${err.code}, message:${err.message}`)
return
}
console.info('success in getting preferences.')
preferences.put('username', 'xiaojiang', (err) => {
if (err){
console.error(`Failed to put the value of 'username',Code ${err.code}, message:${err.message}`)
return;
}
console.info(`Successed in putting the value of 'username'`)
preferences.flush((err) => {
if (err) {
return;
}
preferences.get('username', 'default', (err, val) => {
if (err){
return;
}
console.log(`Success in getting value of 'username', val: ${val}`)
})
})
})
})