1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/yangdechao_admin-guage-notes

В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
22鸿蒙HarmonyOS4.0开发学习.md 25 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 24.06.2025 02:12 0782333

Разработка приложений для HarmonyOS

1. Процесс разработки приложений

Здесь можно вставить изображение описания процесса разработки

2. Процесс выполнения программы

Здесь можно вставить изображение описания процесса выполнения программы

3. Начальные знания о языке ArkTS для HarmonyOS

ArkTS — это предпочтительный язык разработки приложений для OpenHarmony. Язык ArkTS расширяет экосистему TypeScript (сокращенно TS) и сохраняет её базовый стиль, одновременно усиливая статический анализ и проверку во время разработки за счёт определённых норм, что повышает стабильность и производительность выполняемых программ.

Отношения между JavaScript, TypeScript и ArkTS:

JavaScript — это объектно-ориентированный язык программирования, который широко используется для создания веб-приложений. TypeScript — это строго типизированный язык программирования, который расширяет возможности JavaScript, добавляя такие функции, как типизация, модули и декларативное программирование. ArkTS — это язык программирования, который расширяет экосистему TypeScript и добавляет специфические возможности для разработки приложений на платформе HarmonyOS.- JavaScript — это высокоуровневый скриптовый язык, предназначенный для работы в сети, который широко используется в разработке веб-приложений. Он часто применяется для добавления различных динамических функций на веб-страницы, что обеспечивает пользователям более плавное и эстетически приятное взаимодействие.

  • TypeScript — это открытый язык программирования, являющийся надстройкой над JavaScript. Он расширяет синтаксис JavaScript, добавляя статические типы данных, что позволяет создавать более надёжные и масштабируемые приложения.
  • ArkTS основан на языке TypeScript и расширяет его возможности, добавляя поддержку декларативных UI, управления состоянием и параллельных задач.## 4. Основные типы данных в TypeScript

1. Определение переменных

  • В TypeScript переменные могут быть определены с помощью ключевых слов var, let и const, как и в ES6. Формат определения переменной выглядит так: var/let/const идентификатор: тип данных = значение;
var message2: string = 'сообщение';
let message3: string = 'сообщение';
const message1: string = 'сообщение';

2. Простые типы данных

Текстовый тип

let message: string = 'сообщение';

Числовой тип

let num: number = 20;

Логический тип

let boo: boolean = true;

Массив

const arr: number[] = [1, 2, 3, 4, 5];
const arr1: Array<number> = [1, 2, 3, 4, 5]; // Array<number> - определение типа данных

Объект

const obj: {name: string; age: number} = {
    name: "Иван",
    age: 18
};

type objType = {
    name: string,
    age: number
};
const obj1: objType = {
    name: "Иван",
    age: 18
};

3. Сложные типы данных

any- Официальное объяснение: TypeScript имеет специальный тип any. Когда вы не хотите, чтобы определенное значение вызывало ошибки проверки типов, вы можете использовать его.

  • Тип any — это очень специфический тип, предоставляемый TypeScript. Если вы впервые сталкиваетесь с механизмом проверки типов или только начинаете работать с TypeScript, и вам незнаком синтаксис определения типов, вы можете временно использовать any вместо конкретного типа. Однако использование any не рекомендуется, так как это делает проверку типов бессмысленной.
  • Если вы определяете переменную без указания типа, TypeScript не сможет определить её тип из контекста, и эта переменная будет иметь тип any по умолчанию.
  • Если тип переменной — any, она может принимать значения любого типа, то есть почти любой тип будет допустимым.### Базовое использование
let str: any = "123";
let num: any = 123;
let boo: any = true;
let arr: any = [0, 1, 2];
let obj: any = {
  name: "张三",
  age: 18,
};

Пример

Это простой пример использования TypeScript для написания функции, которая выполняет вычисление. В данном случае list: Array<number> — это параметр типа, который представляет собой массив чисел, а возвращаемое значение должно быть числом.

function funAndCalculation(list: Array<number>): number {
  let count = 0;
  list.forEach((item) => {
    count += item;
  });
  return count;
}

console.log(funAndCalculation([1, 2, 3]));

Объединенные типы

  • Объединенный тип состоит из двух или более других типов и представляет собой значение, которое может быть одним из этих типов.
  • В процессе разработки всё может меняться. Например, у вас есть метод, который принимает один параметр, который может быть либо number, либо string. В этом случае вы можете использовать оператор | для объединения типов.
function getUserInfo(id: number | string) {
  console.log(id);
}

getUserInfo("123");
getUserInfo(123);
  • Однако объединённые типы также имеют недостатки. Например, если вы передаёте строковый параметр, TypeScript всё равно покрасит код в красный цвет и сообщит, что метод toUpperCase() не существует.
function getUserInfo(id: number | string) {
  console.log(id.toUpperCase());
}

getUserInfo("1");

img

name: "张三"
```- Решение: Механизм уменьшения типа (более подробно будет рассмотрено позже), где мы используем `typeof` для проверки типа переданного параметра и выполняем соответствующие действия.```js
function getUserInfo(id: number | string) {
  if (typeof id === 'string') {
    console.log(id.toUpperCase());
  } else {
    console.log(id);
  }
}``````js
getUserInfo('a')
getUserInfo(1)

img

Опциональные типы

  • В TypeScript объектные типы также могут указывать, что некоторые или все их свойства являются опциональными.
function printPoint(point: {x: number, y: number, z?: number}) {
  console.log(point.x)
  console.log(point.y)
  console.log(point.z)
}

printPoint({x: 123, y: 321})
printPoint({x: 123, y: 321, z: 111})

img

Утверждение непустого типа

  • Это не является частью TypeScript, а было введено в ES6 для проверки наличия определенного свойства в объекте, что значительно сокращает объем кода.
// message? -> undefined | string
function printMessageLength(message?: string) {
  console.log(message!.length)
}

printMessageLength("aaaa")
printMessageLength("hello world")

Литералные типы

  • Официальное объяснение: помимо общих типов string и number, мы можем использовать конкретные строки и числа в качестве типов.
  • Например, "Hello World" может быть использован как тип. Этот тип называется литеральным типом. Официально: сам по себе литеральный тип не очень ценен.
const message: "Hello World" = "Hello World"

let num: 123 = 123
// num = 321 // Ошибка: невозможно присвоить тип "321" типу "123"

// Литеральные типы имеют смысл при использовании вместе с объединенными типами
type Alignment = 'left' | 'right' | 'center'

let align: Alignment = 'left'
align = 'right'
align = 'center'
// align = 'Hellow' // Ошибка: невозможно присвоить тип "Hellow" типу 'left' | 'right' | 'center'
  • Литеральные типы также поддерживают типовые выводы.В следующем примере функция handleRequest() принимает два параметра: строку url и объединённый тип GET | POST для method. Однако даже если мы передаём GET, TypeScript всё равно выдаёт ошибку, так как он считает тип req.method равным string, что не соответствует требуемому типу handleRequest.
const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);

function handleRequest(url: string, method: "GET" | "POST") {
console.log('object :>> ', url, method);
}

img

Решение 1: Использование типа as "GET | POST"

const req = { url: "https://example.com", method: "GET" as "GET | POST" };
handleRequest(req.url, req.method);

function handleRequest(url: string, method: "GET | POST") {
  console.log('object :>> ', url, method);
}

Решение 2: Использование типа as const

const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);

function handleRequest(url: string, method: "GET | POST") {
  console.log('object :>> ', url, method);
}

Типовые ассерты as

  1. Иногда TypeScript не может получить конкретную информацию о типах, поэтому нам нужно использовать типовые ассерты.
  2. Например, когда мы используем document.getElementById, TypeScript знает, что этот метод вернёт объект типа HTMLElement, но не знает его конкретного типа.
const el = document.getElementById("why") as HTMLImageElement;
el.src = "url адрес";
  1. TypeScript позволяет использовать типовые ассерты для преобразования в более конкретный или менее конкретный тип. Это правило предотвращает невозможные преобразования типов.img

img

const name = "Hello World" as number; // это вызовет ошибку
const name = ("Hello World" as unknown) as number; // это будет работать

Заключение

  • В этой статье были рассмотрены базовые типы данных в TypeScript. Базовые типы не сложны, но все сложные типы строятся на основе этих базовых типов. Умение работать с базовыми типами позволит вам легко использовать TypeScript в ваших проектах.

image-20231222103559386

5. Структура проекта

img

Сверху вниз описывается роль каждого из папок.

.hvigor: хранит конфигурационные данные сборки.

.idea: хранит конфигурационные данные проекта.

AppScope: содержит общие ресурсы проекта.

entry: основной модуль HarmonyOS проекта, который после компиляции создаёт HAP пакет. HAP файлы также находятся здесь.

hvigor: конфигурационные данные сборки, это новый инструмент для управления задачами сборки, реализованный на TypeScript. Он сочетается с npm менеджером пакетов и предоставляет механизмы управления задачами, регистрации задач, моделирования проектов, управления конфигурациями и другими ключевыми возможностями, которые лучше всего подходят для разработчиков ArkTS/JS.

oh_modules: используется для хранения информации о зависимостях сторонних библиотек..gitignore: конфигурация фильтрации для git.

build-profile.json5: конфигурационные данные приложения, включая информацию о подписях и конфигурации продуктов.

hvikorfile.ts: скрипт задач сборки приложения.

hvikorw и hvikorw.bat: инструменты сборки ohpm.

local.properties: файл, содержащий локальные свойства.

oh-package.json5: конфигурация зависимостей, где можно указать зависимости сторонних пакетов.

6. Обзор часто используемых декораторов для разработки приложений HarmonyOS

1. Модификация struct или class

@Entry

Задача: указывает входной компонент, который является точкой входа для компонента. Каждый компонент может иметь только один входной компонент.

Пример: по умолчанию созданный проект содержит @Entry.

@Entry
@Component
struct Index {
  @State message: string = 'Hello World'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}
@Component

Задача: указывает, что текущий struct является компонентом, который можно использовать отдельно или экспортировать для использования другими компонентами.

Пример: использование import/export для экспорта и импорта компонента.

@Component
struct Index {
  @State message: string = 'Hello World'

  build() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
  }
}
@Preview

Задача: предоставляет быстрый способ просмотра отдельных страниц или компонентов с помощью предварительного просмотра DevEco.Использование:

@Preview
@Entry      // Использование @Preview делает @Entry необязательным
@Component
struct TaskPage {
    // ...
}
@Observed

Задача: используется в примерах новостной рассылки, где NewsViewModel работает вместе с декоратором @ObjectLink, чтобы связать несколько компонентов.

Использование:

@Observed
export class CustomRefreshLoadLayoutClass {
  /**
   * Custom refresh load layout isVisible.
   */
  isVisible: boolean;

  /**
   * Custom refresh load layout imageSrc.
   */
  imageSrc: Resource;

  /**
   * Custom refresh load layout textValue.
   */
  textValue: Resource;

  /**
   * Custom refresh load layout heightValue.
   */
  heightValue: number;
}

Второй раздел: модификация переменных

@State

Цель: используется для управления состоянием внутри компонента. Переменные, помеченные этим декоратором, вызывают обновление ArkUI при изменении значений.

Пример:

@Component
struct Index {
  @State message: string = 'Hello World'

  build() {
      Column() {
        Text(this.message)  // В HarmonOS концепция "this" не отвергается!
        // ...
      }
    // ...
  }
}
@Prop

Цель: односторонняя синхронизация состояния от родительского компонента к дочернему компоненту.

TODO: пока в реальном проекте не встречался, если встретится — обновлю

@Link

Цель: двусторонняя синхронизация состояния между родительским и дочерним компонентами.

Использование:

Родительский компонент

// ...

@Preview
@Component
export default struct TabBar {
  @State tabBarArray: NewsTypeBean[] = NewsViewModel.getDefaultTypeList();
  @State currentIndex: number = 0;     // Определение переменной состояния
  @State currentPage: number = 1;
}
``````md
// Определение слушательской функции
changeCategory() {
  this.newsModel.currentPage = 1;
  NewsViewModel.getNewsList(this.newsModel.currentPage, this.newsModel.pageSize, Const.GET_NEWS_LIST)
    .then((data: NewsData[]) => {
      this.newsModel.pageState = PageState.Success;
      if (data.length === this.newsModel.pageSize) {
        this.newsModel.currentPage++;
        this.newsModel.hasMore = true;
      } else {
        this.newsModel.hasMore = false;
      }
      this.newsModel.newsData = data;
    })
    .catch((err: string | Resource) => {
      promptAction.showToast({
        message: err,
        duration: Const.ANIMATION_DURATION
      });
      this.newsModel.pageState = PageState.Fail;
    });
}

aboutToAppear() {
  // Запрос данных новостей
  this.changeCategory();
}

@Watch

Используется вместе с @Link, чтобы слушать изменения состояния.

Пример использования: см. предыдущий пример.

@Provide [в процессе обновления]

Задача: для межкомпонентной связи, позволяет модифицировать переменные в родительских компонентах.

@Consume [в процессе обновления]

Задача: для межкомпонентной связи, позволяет модифицировать переменные в дочерних компонентах.

@ObjectLink [в процессе обновления]

```Используется вместе с классами, отмеченными @Observed, для конкретных действий, которые ещё предстоит изучить.

TODO: пока не понимаем конкретных действий, нет подходящих примеров, поэтому временно не предоставляем.

Три: декораторы функций

Использование декораторов для функций позволяет нам выделить избыточные стили и повторяющиеся логические конструкции, что снижает сложность кода.

@Builder

Задача: используется для декорирования функций, чтобы быстро создавать контент разметки, избегая написания повторяющихся стилей. Можно создать переиспользуемый компонент со стилями.

Пример:

@Component
export default struct TodoItem {

  @State isComplete: boolean = false;
  @Builder labelIcon(url) {
    Image(url)
      .objectFit(ImageFit.Contain)
      .width(24)
      .height(24)
      .margin({
        right: 15,
        top: 5
      })
  }

  build() {
    Row() {
      if (this.isComplete) {
        this.labelIcon($r("app.media.select"))
      } else {
        this.labelIcon($r("app.media.unselect"))
      }

      // ..
    }
  }
}

@Style

Задача: используется для декорирования функций, чтобы сохранять стили и предоставлять их компонентам.

Синтаксис:

// Общие стили для карточки
@Styles function card() {
  .width('95%')
  .padding(20)
  .backgroundColor(0xffffff)
  .borderRadius(15)
  .shadow({ radius: 6, color: 0x1F000000, offsetX: 2, offsetY: 4})
}

@Extend

Задача: наследует встроенный компонент и позволяет разработчику расширять его другими часто используемыми свойствами.

Синтаксис:```js @Extend(Text) function finishedTask() { .decoration({ type: TextDecorationType.LineThrough }) .fontColor(0xB1B2B1) }


Пример:

```js
    // ...

    Row() {
        Text(item.name)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .finishedTask()
    }

    // ...

// Этот код должен быть вне структуры файла
@Extend(Text) function finishedTask() {
  .decoration({ type: TextDecorationType.LineThrough })
  .fontColor(0xB1B2B1)
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/yangdechao_admin-guage-notes.git
git@api.gitlife.ru:oschina-mirror/yangdechao_admin-guage-notes.git
oschina-mirror
yangdechao_admin-guage-notes
yangdechao_admin-guage-notes
master