笔者是做前端的,在学习鸿蒙的时候,一直好奇能不能像vue一样,做到数据双向绑定,实现像vue的MvvM一样,数据和视图双向同步。
即实现:数据变化-视图更新,视图更新-数据更新
数据绑定可分为单向数据绑定和双向数据绑定。单向数据绑定指的是对象实例的数据更新会引起界面元素的更新,反之不行;双向数据绑定指的是对象实例的数据更新会引起界面元素的数据更新,界面元素的数据更新也会引起对象实例的数据更新。
因为像这种通过事件来同步数据的办法,太繁琐了
@Entry
@Component
struct Index {
@State
value: string = 'Hello Word'
build() {
Column({ space: 12 }) {
Text(this.value)
TextInput({ text: this.value }).onChange((value) => {
// 事件产生的UI更新不会同步给数据,需要手动赋值
this.value = value
})
}
.width("100%")
.height("100%")
}
}
然后就在官方文档中,找到了这个$$语法:内置组件双向同步
使用规则
- 当前$$支持基础类型变量,以及@State、@Link和@Prop装饰的变量。
- 当前$$支持的组件:
| 组件 | 支持的参数/属性 | 起始API版本 |
|---|---|---|
| Checkbox | select | 10 |
| CheckboxGroup | selectAll | 10 |
| DatePicker | selected | 10 |
| TimePicker | selected | 10 |
| MenuItem | selected | 10 |
| Panel | mode | 10 |
| Radio | checked | 10 |
| Rating | rating | 10 |
| Search | value | 10 |
| SideBarContainer | showSideBar | 10 |
| Slider | value | 10 |
| Stepper | index | 10 |
| Swiper | index | 10 |
| Tabs | index | 10 |
| TextArea | text | 10 |
| TextInput | text | 10 |
| TextPicker | selected、value | 10 |
| Toggle | isOn | 10 |
| AlphabetIndexer | selected | 10 |
| Select | selected、value | 10 |
| BindSheet | isShow | 10 |
| BindContentCover | isShow | 10 |
| Refresh | refreshing | 8 |
| GridItem | selected | 10 |
| ListItem | selected | 10 |
使用示例
interface UserInfoType {
name: string
age: string
}
@Entry
@Component
struct MvvmCase {
@State text: string = 'Hello world'
@State select: string = '请选择'
@State radio: boolean = false
@State userInfo: UserInfoType = {
name: '张三',
age: '18'
}
build() {
Column({ space: 12 }) {
Column() {
Text('TextInput双向绑定')
TextInput({ text: $$this.text })
// 注意:不能拿对象的属性双向数据绑定,会报错
// TextInput({ text: $$this.userInfo.name })
Text(this.text)
}.margin({ bottom: 20 })
Column() {
Text('Select双向绑定')
Select([{
value: '黄金糕',
}, {
value: '双皮奶',
}, {
value: '蚵仔煎',
}, {
value: '龙须面',
}, {
value: '北京烤鸭',
}])
.value($$this.select)
Text('' + this.select)
}.margin({ bottom: 20 })
Column() {
Text('Radio双向绑定')
Radio({ value: 'radio', group: 'radioSelect' }).checked($$this.radio)
Text('' + this.radio)
}.margin({ bottom: 20 })
}
.width("100%")
.height("100%").padding(20)
}
}
注意事项
- 不支持嵌套数据的双向绑定
- api版本10+及以上