参考 #
页面组件 #
@Entry
@Component
struct Index {
// 工程默认显示 `Index` 页面组件
// build 是声明UI的位置
build() {
Text('页面组件')
}
}
自定义组件
// 定义 `Footer` 组件
@Component
struct Footer {
build() {
Text('自定义组件')
}
}
@Entry
@Component
struct Index {
build() {
Column(){
// 使用 `Footer` 组件
Footer()
}
}
}
导出使用
@Component
export default struct Footer {
build() {
Text('自定义组件')
}
}
import Footer from './components/Footer.ets'
@Entry
@Component
struct Index {
build() {
Column(){
// 使用 `Footer` 组件
Footer()
}
}
}
系统组件 #
参考基础组件
样式处理 #
链式 #
- 样式属性
@Entry
@Component
struct Index {
build() {
Text('演示')
.backgroundColor('red')
.fontSize(50)
.width('100%')
.height(100)
}
}
- 枚举值
@Entry
@Component
struct Index {
build() {
Text('演示')
.fontSize(50)
.width('100%')
.height(100)
.backgroundColor(Color.Blue)
.textAlign(TextAlign.Center)
.fontColor(Color.White)
}
}
常用 #
伸缩 layoutWeight(flex: number)
占剩余空间多少份,可以理解成CSS的 flex: 1
@Entry
@Component
struct Index {
build() {
Row(){
Text('left')
.layoutWeight(1)
.backgroundColor('red')
Text('right')
.layoutWeight(2)
.backgroundColor('green')
}
.width('100%')
}
}
等比例,设置元素宽高比 aspectRatio(ratio: number)
@Entry
@Component
struct Index {
build() {
Text('left')
.width('50%')
// 宽高比例
.aspectRatio(1)
.backgroundColor('red')
}
}
样式复用@Style #
// 全局
@Styles
function functionName() { ... }
@Entry
@Component
sturt Index{
// 组件内
@Styles
functionName() { ... }
build() {
Text('Text')
.functionName()
}
}
例如,简单吧.
我似乎懂了,@Style只能用于公共样式,没法为空间设置单独的样式,所以还是用@Extends
@Entry
@Component
struct Index {
@State
count: number = 10
// 不需要 `function` 关键字,覆盖全局
@Styles
sameStyle (){
.backgroundColor(Color.Pink)
.onClick(() => {
this.count += 10
})
}
build() {
Column() {
Text(this.count.toString())
.width(100)
.height(50)
.margin({ bottom: 10 })
.textAlign(TextAlign.Center)
.sameStyle()
Button('+1')
.sameStyle()
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
样式复用@Extends #
// 全局 原生组件 参数
// ↓ ↓ ↓
@Extend(Text) function functionName(w: number) {
.width(w)
}
例如
import promptAction from '@ohos.promptAction'
@Extend(Text) function myClick(color: string, cb: () => void) {
.backgroundColor(color)
.width(100)
.height(50)
.textAlign(TextAlign.Center)
.borderRadius(25)
.onClick(() => cb())
}
@Entry
@Component
struct Other {
@State
color: string = '#ccc'
build() {
Column({ space: 20 }) {
Text('Text1')
.myClick(this.color, () => {
this.color = '#069'
})
Text('Text2')
.myClick('green', () => {
promptAction.showToast({ message: '做其他事~' })
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
样式多态 #
stateStyles
是属性方法,可以根据UI内部状态来设置样式,类似于 css 伪类,但语法不同。
- focused:获焦态。
- normal:正常态。
- pressed:按压态。
- disabled:不可用态。
normal和pressel这两用的比较多
import promptAction from '@ohos.promptAction'
// 胶囊按钮
@Extend(Text)
function capsule(){
.height(40)
.borderRadius(20)
.backgroundColor(Color.Gray)
.padding({ left: 15, right: 15 })
.margin({ bottom: 15 })
}
@Entry
@Component
struct Index {
@State
disabled: boolean = false
@State
focused: boolean = false
build() {
Column() {
// Button TextInput 默认开启获取焦点,页面中默认第一个这样的元素获取焦点
// Button 比较多限制,一个是默认开启获取焦点能看,二是禁用状态下样式无法修改
// Button('Button').focusable(false)
Text('toggle disabled:' + this.disabled)
.capsule()
.onClick(()=>{
this.disabled = !this.disabled
})
Text('toggle focused:' + this.focused)
.capsule()
.onClick(()=>{
this.focused = !this.focused
})
Text('clickMe')
.capsule()
.enabled(!this.disabled)
.focusable(this.focused)
.onClick(() => {
promptAction.showToast({ message: 'click' })
})
.fontColor('#fff')
.stateStyles({
normal: {
.backgroundColor(Color.Blue)
},
focused: {
.backgroundColor(Color.Red)
},
disabled: {
.backgroundColor(Color.Black)
},
pressed: {
.backgroundColor(Color.Orange)
}
})
}
}
}
组件状态 #
class 语法 #
这个简单。首先,class
创建对象和 class
类型
class Person {
age: number;
name: string;
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
// 当类型使用和构当造函数使用
const p: Person = new Person('jack', 18)
// 当类型使用这种使用后续居多,我们使用字面量对象居多,可以省略 constructor
const p1: Person = {
name: 'tom',
age: 20
}
implements
实现 interface
接口
interface IPerson {
name: string,
age: number,
say: () => void
}
// 实现 IPerson 接口,需要符合接口约定
class Person implements IPerson{
age: number;
name: string;
constructor(name: string, age: number) {
this.name = name
this.age = age
}
say () {
promptAction.showToast({ message: this.name })
}
}
继承
class HmPerson extends Person {
github: string = 'https://github.com/zhousg'
coding () {
promptAction.showToast({ message: this.name + ': coding' })
}
}
界面渲染 #
条件渲染 #
这个就不用多说了吧,Vue和React都有学过
循环渲染 #
语法 ,其实很多都是差不多的
ForEach(
// 数据源
arr: Array,
// 组件生成函数
itemGenerator: (item: Array, index?: number) => void,
// 键值生成函数
keyGenerator?: (item: Array, index?: number): string => string
)
来个实例
class User {
id: string
name: string
age: number
}
@Entry
@Component
struct Index {
@State
userList: User[] = []
build() {
Scroll() {
Column({ space: 20 }) {
// 循环渲染
ForEach(
// 1. 数据源
this.userList,
// 2. 组件生成函数
(item: User) => {
// 内容
Text(`${item.name} 今年 ${item.age} 岁`)
},
// 3. 键值生成函数
item => item.id
)
Button('加载更多')
.onClick(() => {
const arr: User[] = []
for (let index = 0; index < 10; index++) {
arr.push({ id: Math.random().toString(), name: 'jack', age: Math.ceil(Math.random() * 100) })
}
this.userList.push(...arr)
})
}
}
.width('100%')
}
}
注意:
其中的key尽量别缺,也尽量不要使用index,使用唯一的id之类的