住房和城乡建设部网站职称查询,网站建设和管理颁奖,大淘客做网站视频,学技能的免费网站官方文档#xff1a;MVVM模式 [QA] 什么是MVVM
ArkUI采取MVVM Model View ViewModel模式。
Model层#xff1a;存储数据和相关逻辑的模型。View层#xff1a;在ArkUI中通常是Component装饰组件渲染的UI。ViewModel层#xff1a;在ArkUI中#xff0c;ViewModel是…官方文档MVVM模式 [QA] 什么是MVVM
ArkUI采取MVVM Model View ViewModel模式。
Model层存储数据和相关逻辑的模型。View层在ArkUI中通常是Component装饰组件渲染的UI。ViewModel层在ArkUI中ViewModel是存储在自定义组件的状态变量、LocalStorage和AppStorage中的数据。
MVVM应用示例
开发一个电话簿应用实现功能如下
显示联系人和设备“Me”电话号码 。选中联系人时进入可编辑态“Edit”可以更新该联系人详细信息包括电话号码住址。在更新联系人信息时只有在单击保存“Save Changes”之后才会保存更改。可以点击删除联系人“Delete Contact”可以在联系人列表删除该联系人。
Model
AddressPersonAddressBookMyArray
ViewModel
PersonViewphonesNumberPersonEditViewAddressBookView
Vidw
PracExample
// ViewModel classes
let nextId 0;Observed
export class MyArrayT extends ArrayT {constructor(args: T[]) {console.log(MyArray: ${JSON.stringify(args)} )if (args instanceof Array) {super(...args);} else {super(args)}}
}Observed
export class Address {street: string;zip: number;city: string;constructor(street: string,zip: number,city: string) {this.street street;this.zip zip;this.city city;}
}Observed
export class Person {id_: string;name: string;address: Address;phones: MyArraystring;constructor(name: string,street: string,zip: number,city: string,phones: string[]) {this.id_ ${nextId};nextId;this.name name;this.address new Address(street, zip, city);this.phones new MyArraystring(phones);}
}export class AddressBook {me: Person;friends: MyArrayPerson;constructor(me: Person, contacts: Person[]) {this.me me;this.friends new MyArrayPerson(contacts);}
}// 渲染出Person对象的名称和Observed数组string中的第一个号码
// 为了更新电话号码这里需要ObjectLink person和ObjectLink phones
// 不能使用this.person.phones内部数组的更改不会被观察到。
// 在AddressBookView、PersonEditView中的onClick更新selectedPerson
Component
struct PersonView {ObjectLink person: Person;ObjectLink phones: MyArraystring;Link selectedPerson: Person;build() {Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {Text(this.person.name)if (this.phones.length) {Text(this.phones[0])}}.height(55).backgroundColor(this.selectedPerson.name this.person.name ? Color.Pink : #ffffff).onClick(() {this.selectedPerson this.person;})}
}Component
struct phonesNumber {ObjectLink phoneNumber: MyArraystringbuild() {Column() {ForEach(this.phoneNumber,(phone: ResourceStr, index?: number) {TextInput({ text: phone }).width(150).onChange((value) {console.log(${index}. ${value} value has changed)this.phoneNumber[index!] value;})},(phone: ResourceStr, index: number) ${this.phoneNumber[index] index})}}
}// 渲染Person的详细信息
// Prop装饰的变量从父组件AddressBookView深拷贝数据将变化保留在本地, TextInput的变化只会在本地副本上进行修改。
// 点击 Save Changes 会将所有数据的复制通过Prop到Link, 同步到其他组件
Component
struct PersonEditView {Consume addrBook: AddressBook;/* 指向父组件selectedPerson的引用 */Link selectedPerson: Person;/*在本地副本上编辑直到点击保存*/Prop name: string ;Prop address: Address new Address(, 0, );Prop phones: MyArraystring [];selectedPersonIndex(): number {return this.addrBook.friends.findIndex((person: Person) person.id_ this.selectedPerson.id_);}build() {Column() {TextInput({ text: this.name }).onChange((value) {this.name value;})TextInput({ text: this.address.street }).onChange((value) {this.address.street value;})TextInput({ text: this.address.city }).onChange((value) {this.address.city value;})TextInput({ text: this.address.zip.toString() }).onChange((value) {const result Number.parseInt(value);this.address.zip Number.isNaN(result) ? 0 : result;})if (this.phones.length 0) {phonesNumber({ phoneNumber: this.phones })}Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {Text(Save Changes).onClick(() {// 将本地副本更新的值赋值给指向父组件selectedPerson的引用// 避免创建新对象在现有属性上进行修改this.selectedPerson.name this.name;this.selectedPerson.address new Address(this.address.street, this.address.zip, this.address.city)this.phones.forEach((phone: string, index: number) {this.selectedPerson.phones[index] phone});})if (this.selectedPersonIndex() ! -1) {Text(Delete Contact).onClick(() {let index this.selectedPersonIndex();console.log(delete contact at index ${index});// 删除当前联系人this.addrBook.friends.splice(index, 1);// 删除当前selectedPerson选中态前移一位index (index this.addrBook.friends.length) ? index : index - 1;// 如果contract被删除完则设置me为选中态this.selectedPerson (index 0) ? this.addrBook.friends[index] : this.addrBook.me;})}}}}
}Component
struct AddressBookView {ObjectLink me: Person;ObjectLink contacts: MyArrayPerson;State selectedPerson: Person new Person(, , 0, , []);aboutToAppear() {this.selectedPerson this.me;}build() {Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start }) {Text(Me:)PersonView({person: this.me,phones: this.me.phones,selectedPerson: this.selectedPerson})Divider().height(8)ForEach(this.contacts, (contact: Person) {PersonView({person: contact,phones: contact.phones as MyArraystring,selectedPerson: this.selectedPerson})}, (contact: Person): string {return contact.id_;})Divider().height(8)Text(Edit:)PersonEditView({selectedPerson: this.selectedPerson,name: this.selectedPerson.name,address: this.selectedPerson.address,phones: this.selectedPerson.phones})}.borderStyle(BorderStyle.Solid).borderWidth(5).borderColor(0xAFEEEE).borderRadius(5)}
}Entry
Component
struct PracExample {Provide addrBook: AddressBook new AddressBook(new Person(卧龙, 南路 9, 180, 大连, [18*********, 18*********, 18*********]),[new Person(小华, 东路 9, 180, 大连, [11*********, 12*********]),new Person(小刚, 西边路 9, 180, 大连, [13*********, 14*********]),new Person(小红, 南方街 9, 180, 大连, [15*********, 168*********]),]);build() {Column() {AddressBookView({me: this.addrBook.me,contacts: this.addrBook.friends,selectedPerson: this.addrBook.me})}}
}