微信的网站开发,网站空间内存,如何申请开通网站,国家级门户网站有哪些文章目录 前言一、ArkTS基本介绍1、 ArkTS组成2、组件参数和属性2.1、区分参数和属性的含义2.2、父子组件嵌套 二、装饰器语法1.State2.Prop3.Link4.Watch5.Provide和Consume6.Observed和ObjectLink代码示例#xff1a;示例1#xff1a;#xff08;不使用Observed和ObjectLi… 文章目录 前言一、ArkTS基本介绍1、 ArkTS组成2、组件参数和属性2.1、区分参数和属性的含义2.2、父子组件嵌套 二、装饰器语法1.State2.Prop3.Link4.Watch5.Provide和Consume6.Observed和ObjectLink代码示例示例1不使用Observed和ObjectLink示例2使用Observed和ObjectLink 三、总结四、未完待更 前言
HarmonyOS NEXT鸿蒙应用开发快速入门教程ArkTS语法之装饰器篇基于HarmonyOS NEXT Beta1版本api 12讲解。 本文将从前端开发者角度来理解和学习每个语法点通过举例HarmonyOS NEXT和web端两种领域类似语法的使用帮助前端开发人员快速入门HarmonyOS NEXT。在每个装饰器讲解上把同一个功能分别用ArkTs和vue 2种代码进行演示使其更深刻理解每个装饰器的作用在类比中学习记忆达到无缝衔接。 一、ArkTS基本介绍 ArkTs是鸿蒙开发主要语言在以TS为语法基础上进行部分扩展和约束以提升程序执行稳定性和性能。ArkTs可以看成严格模式的TS并结合声明式UI进行页面布局。ArkTs吸收各家语言优点形成一种全新语法在ArkTs身上我们到处都能看到web、vue、flutter、安卓等前端领域语法的身影 1、 ArkTS组成 说明 1、以开头为装饰器装饰器都有固定英文名称不同装饰器有着不同作用。例如Entry表示当前组件为页面级别组件页面路由入口Component声明该文件为组件 State声明一个可引起UI响应式的变量等等 2、struct 后面跟着组件名称固定写法struct 类似es6 类里面关键字class 后面的组件名称可以自定义内部语法也类似class类语法包括方法和属性添加 3、UI描述固定放置在build函数里面换句话说build函数里面主要写布局代码 4、系统组件一些系统自带的组件例如文字Text、按钮(Button)、输入框(TextInput)等类似web里面dom标签,子组件通过嵌套标签写法引入组件的属性和事件通过链式调用。
2、组件参数和属性
2.1、区分参数和属性的含义 组件标签函数入参称为组件参数也即括号内的内容而点后面的链式调用函数称为属性事件和属性一样也通过链式函数调用 示例2.1 build() {Column(){Button(按钮).type(ButtonType.Capsule).onClick((){console.log(click)})}.width(500px).height(200px).backgroundColor(Color.Black)}
如上述示例所示按钮’为组件Button入参type为Button属性onClick为Button点击事件width、height、backgroundColor为组件Column属性。
所有组件都有通用属性通用属性大部分类似web里的css属性例如设置组件的尺寸宽高、位置、背景、透明度等。
2.2、父子组件嵌套
父组件花括号{}内写子组件如示例2.1Column为父组件Button为子组件如果没有子组件可以省略{},如示例2.1的Button
示例2.1等价于如下的html写法 div styleheight:200px;width:500px;background:blackbutton 按钮/button/div二、装饰器语法 常用的装饰器语法跟vue很像本模块将通过ArkTs示例结合web主要vue示例演示对比使其更好的理解和掌握ArkTs装饰器的使用。 1.State State用来装饰变量通过State装饰的变量改变后才能触发UI刷新而普遍变量改变不触发UI刷新相当于Vue3的ref 语法State 变量名类型值
//例如
State sex:string男示例
ArkTs写法
Entry
Component
struct Demo {State name:string小红//姓名age:number10//年龄build() {Column({space:10}){Text(姓名${this.name}).fontColor(Color.Black)Text(年龄${this.age}).fontColor(Color.Black)Button(点击改变姓名).onClick((){this.name小明})Button(点击改变年龄).onClick((){this.age20})}}
}
等价于
Vue3写法:
templatediv styledisplay:flex;flex-direction: column;span姓名{{name}}/spanspan年龄{{age}}/spanbutton clickonChangeName点击改变姓名/buttonbutton clickonChangeAge点击改变年龄/button/div
/template
script setup
import {ref} from vue
const nameref(小红)
let age10const onChangeName(){name.value小明
}
const onChangeAge(){age20
}/script运行效果
上述示例name姓名变量用State修饰而age年龄变量为普通变量当点击改变姓名按钮姓名变成小红当点击改变年龄按钮年龄不变
2.Prop Prop用来定义子组件的入参和父组件建立单向的同步关系相当于vue中的prop区别在于vue中的prop不允许改变值而鸿蒙中可以随意改变值但是改变后的值不会同步回其父组件也就是数据是单向传递。 语法Prop 变量名类型默认值
Prop size:number20示例
ArkTs写法 //父组件
Entry
Component
struct Parent {State city:string上海build() {Column({space:20}) {//引入子组件Child({city:this.city})Button(定位).onClick((){this.city深圳})}}
}//子组件
Component
struct Child{Prop city:string北京 //默认值北京build() {Column({space:10}) {Text(当前所处城市${this.city}).fontSize(20)}}
}
等价于
Vue3写法:
child.vue子组件:
templatedivspan当前所处的城市{{city}}/span/div
/template
script setup
const propsdefineProps({city:{type:String,default:北京}
})/scriptparent.vue父组件
templatediv styledisplay:flex;flex-direction: column;Child :citycity/Childbutton clickonLocation定位/button/div
/template
script setup
import {ref} from vue
import Child from ./child.vue
const cityref(上海)
//定位点击事件
const onLocation(){city.value深圳
}/script
style scoped/style 运行效果
ps:ArkTS支持在同一个文件内自定义多个组件也可以分出去单独写子组件通过import导入
3.Link Link用来定义子组件入参和父组件建立双向绑定关系相当于vue中的v-model,区别在于Link是直接在子组件内修改数据源,而v-model是语法糖本质通过事件通知父组件来改变值。 语法Link 变量名类型
Link loop:boolean示例
ArkTs写法
//父组件
Entry
Component
struct Parent {State value: string //输入内容build() {Column({ space: 20 }) {Text(输入框值为${this.value})Child({ value: this.value })}.padding(20)}
}//子组件
Component
struct Child {Link value: string //输入内容build() {//输入框TextInput({ text: this.value }).onChange((value: string) { //输入事件监听this.value value})}
}
等价于
Vue3写法:
child.vue子组件:
templateinput :valuemodelValue inputonChange/
/template
script setup
const propsdefineProps({modelValue:{type:String,default:}
})const emitsdefineEmits([update:modelValue])//输入事件监听
const onChange(e){console.log(e,e)emits(update:modelValue,e.target.value)
}/scriptparent.vue父组件
templatediv styledisplay:flex;flex-direction: column;span输入框值为{{value}}/spanChild v-modelvalue/Child/div
/template
script setup
import {ref} from vue
import Child from ./child.vue//输入内容
const valueref()/script
style scoped/style 运行效果 ps:Link修饰的变量不能设置默认值
4.Watch Watch用于对状态变量的监听当变量值变化会触发回调。相当于vue中 watch。 语法 其他装饰器 Watch(回调函数名) 变量名类型值 或 Watch(回调函数名) 其他装饰器 变量名类型值
推荐Watch写在其他装饰器后面
State Watch(onIndexChange) index:number0
//监听值改变回调
onIndexChange(){
} 区别和注意点 1、Watch无法获取旧值相当于无vue-watch的oldValue入参 2、Watch无法深度监听相当vue-watch的deep属性为false 3、Watch无法设置初始化触发相当vue-watch的immediate属性为false 4、Watch可监听所有装饰器装饰的状态变量。不允许监听常规变量 5、Watch对于数组监听能力跟vue2对数组响应式监听一样能监听到push、pop、splice、shift、unshift等数组操作变化
示例
ArkTs写法
//父组件
Entry
Component
struct Demo {private price: number 10 //单价State Watch(onCountChange) count:number1//数量State total:number10 //总价//数量变化监听onCountChange(){this.totalthis.price*this.count}build() {Column({ space: 20 }) {Text(单价${this.price})Text(数量x${this.count})Text(总价${this.total})Button(数量1).onClick((){this.count})}.padding(20).alignItems(HorizontalAlign.Start)}
}//子组件
Component
struct Child {Link value: string //输入内容build() {//输入框TextInput({ text: this.value }).onChange((value: string) { //输入事件监听this.value value})}
}
等价于
Vue3写法:
templatediv styledisplay:flex;flex-direction: column;span单价{{price}}/spanspan数量x{{count}}/spanspan总价{{total}}/spanbutton clickonCountChange数量1/button/div
/template
script setup
import {ref,watch} from vue
//单价
const priceref(10)
//数量
const countref(1)
//总价
const totalref(10)
//数量1
const onCountChange(){count.value
}
watch(count,(newValue,oldValue){total.valueprice.value*newValue
})/script
style scoped/style 运行效果 从上述例子可以看出watch回调函数中无任何入参获取新值是通过重新访问属性值来获取而旧值无法获取这是第一点不足。第二点不足无法深层监听对象第三点不足只能监听单个值变化无法像vue3可以监听多个值。好在下一个装饰器语法版本v2版本将对这些不足点进行改进并支持目前v2版本处于试用开发阶段还不成熟这里不过多介绍。
5.Provide和Consume Provide和Consume成对使用作用是把参数往子孙层传递实现跨层级多层级传递。父组件使用Provide修饰变量参数子孙组件使用Consume接收变量参数跟vue3的ProvideConsume使用机制一样。 两种写法
// 通过相同的变量名绑定
Provide a: number 0;
Consume a: number;// 通过相同的变量别名绑定
Provide(a) b: number 0;
Consume(a) c: number;示例
ArkTs写法
//父组件
Entry
Component
struct Parent {Provide(weight) weight: number 50build() {Column({ space: 20 }) {Text(父组件体重值:${this.weight})Button(父组件体重1).onClick(() {this.weight})Child()}.padding(20).alignItems(HorizontalAlign.Start)}
}//子组件
Component
struct Child {build() {Grandson()}
}//孙组件
Component
struct Grandson {Consume(weight) weight: numberbuild() {Column({ space: 20 }) {Text(孙组件体重值:${this.weight})Button(孙组件体重1).onClick(() {this.weight})}.margin({ top: 50 })}
}
等价于
Vue3写法:
parent.vue父组件:
templatedivspan父组件体重值{{ weight }}/spanbutton clickonAdd父组件体重1/buttonChild//div
/templatescript setup
import { ref,provide } from vue;
import Child from ./child.vueconst weightref(50)
provide(weight,weight)
const onAdd(){weight.value
}/script
child.vue子组件:
templateGrandson/
/templatescript setup
import Grandson from ./grandson .vue;
/script
grandson.vue孙组件
templatedivspan孙组件体重值{{ weight }}/spanbutton clickonAdd孙组件体重1/button/div/templatescript setupimport { ref,inject } from vue;const weightinject(weight,50)const onAdd(){weight.value}/script
运行效果 ps:Consume修饰的变量不能设置默认值
6.Observed和ObjectLink 对于对象类型的数据劫持鸿蒙和vue不一样不管是State、Prop、Link或者ProvideConsume对于对象类型的数据只能监听到最外层变化当对象嵌套多层对象内部对象的属性值改变将无法响应UI变化Observed和ObjectLink就是为了解决这个问题而设计的。 使用方法 1、Observed用来修饰类也即TS对象类型被Observed装饰的类可以被观察到属性的变化每一层的类都需要用Observed修饰才能生效。 2、ObjectLink装饰器在子组件中使用用于装饰Observed装饰的类的实例和父组件中对应的状态变量建立双向数据绑定也可以看成子组件的入参变量。 3、Observed和ObjectLink要配合自定义子组件使用才能生效而且每嵌套一层就要抽离出一个子组件引入简单理解就是每一层数据当入参传入子组件。
语法示例
Observed
class xxx{constructor(){}
}子组件 ObjectLink 变量名:类型代码示例 场景设计—— 假设有个学生对象数据对象里包含姓名、性别、和成绩属性成绩属性又是个对象包含语文、数学、英文分数属性。通过改变学生性别和分数观察UI变化。 示例1不使用Observed和ObjectLink
//学生对象
class Student {name: string //姓名sex: string //性别score: ScoreData //分数对象constructor(name: string, sex: string, score: ScoreData) {this.name namethis.sex sexthis.score score}
}//分数对象
class ScoreData {math: number //数学chinese: number //语文english: number //英语constructor(math: number, chinese: number, english: number) {this.math maththis.chinese chinesethis.english english}
}Entry
Component
struct Demo {//学生对象实例State student:Studentnew Student(王明,男,new ScoreData(80,90,75))build() {Column({space:10}) {Text(姓名:${this.student.name})Text(性别:${this.student.sex})Text(数学成绩:${this.student.score.math}分)Text(语文成绩:${this.student.score.chinese}分)Text(英语成绩:${this.student.score.english}分)Button(改变性别).onClick((){this.student.sex女})Button(改变数学成绩).onClick((){this.student.score.math10})}.width(100%).padding(20).alignItems(HorizontalAlign.Start)}
}运行效果 从运行效果可以看出性别变了而数学分数未变因为数学分数math属性属于对象中第二层数据State无法观察到多层变化而性别sex属性属于第一层可以观察到变化。
示例2使用Observed和ObjectLink
//学生对象
Observed
class Student {name: string //姓名sex: string //性别score: ScoreData //分数对象constructor(name: string, sex: string, score: ScoreData) {this.name namethis.sex sexthis.score score}
}//分数对象
Observed
class ScoreData {math: number //数学chinese: number //语文english: number //英语constructor(math: number, chinese: number, english: number) {this.math maththis.chinese chinesethis.english english}
}Entry
Component
struct Demo {//学生对象实例State student: Student new Student(王明, 男, new ScoreData(80, 90, 75))build() {Column({ space: 10 }) {Text(姓名:${this.student.name})Text(性别:${this.student.sex})ScoreView({data: this.student.score})Button(改变性别).onClick(() {this.student.sex 女})Button(改变数学成绩).onClick(() {this.student.score.math 10})Button(改变语文成绩).onClick(() {this.student.score.chinese--})}.width(100%).padding(20).alignItems(HorizontalAlign.Start)}
}//子组件
Component
struct ScoreView {ObjectLink data: ScoreData //分数对象build() {Column() {Text(数学成绩:${this.data.math}分)Text(语文成绩:${this.data.chinese}分)Text(英语成绩:${this.data.english}分)}}
}运行效果 从运行效果可以看出因为使用了Observed和ObjectLink所以修改第二层数据数学和英文成绩都会响应UI变化。
小结 通过上面示例演示来看鸿蒙对嵌套对象场景的开发显得力不从心如果数据对象是n层就需要自定义n-1个子组件来传递每一层的数据特别麻烦。好在官方已经注意到这些不足在下个版本v2版提供的新的装饰器ObservedV2Trace解决对象嵌套问题v2版本目前处于开发试用阶段还没正式发布这里不过多介绍有兴趣可以自行查阅官网文档。 ps:对于多层嵌套场景不单单指对象中嵌套对象还包括对象中嵌套数组或者数组中嵌套对象因为在js世界里数组也是对象类型。 三、总结 上述6种装饰器语法是开发中比较高频率使用的装饰器可以看出除了第六个剩下的都可以在vue中找到对应的语法使用上几乎一样所以从事前端开发特别是vue技术栈的开发人员可以快速无缝衔接。 四、未完待更
除了上述6种常用装饰器ArkTs还有一些其他比较重要装饰器将在下篇博文继续介绍。。。。。。