js-framework-syntax-js.md 9.4 KB
Newer Older
Z
zengyawen 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
# JS语法参考

JS文件用来定义HML页面的业务逻辑,支持ECMA规范的JavaScript语言。基于JavaScript语言的动态化能力,可以使应用更加富有表现力,具备更加灵活的设计能力。下面讲述JS文件的编译和运行的支持情况。


## 语法

支持ES6语法。

- 模块声明
  使用import方法引入功能模块:

  ```
  import router from '@system.router';
  ```

- 代码引用
  使用import方法导入js代码:

  ```
  import utils from '../../common/utils.js';
  ```


## 对象

- 应用对象
  | 属性 | 类型 | 描述 |
  | -------- | -------- | -------- |
  | $def | Object | 使用this.$app.$def获取在app.js中暴露的对象。<br/>>&nbsp;![icon-note.gif](public_sys-resources/icon-note.gif)&nbsp;**说明:**<br/>>&nbsp;应用对象不支持数据绑定,需主动触发UI更新。 |

  示例代码

  ```
  // app.js
  export default {
    onCreate() {
Z
zengyawen 已提交
38
      console.info('Application onCreate');
Z
zengyawen 已提交
39 40
    },
    onDestroy() {
Z
zengyawen 已提交
41
      console.info('Application onDestroy');
Z
zengyawen 已提交
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
    },
    globalData: {
      appData: 'appData',
      appVersion: '2.0',
    },
    globalMethod() {
      console.info('This is a global method!');
      this.globalData.appVersion = '3.0';
    }
  };
  ```

  ```
  // index.js页面逻辑代码
  export default {
    data: {
      appData: 'localData',
      appVersion:'1.0',
    },
    onInit() {
      this.appData = this.$app.$def.globalData.appData;
      this.appVersion = this.$app.$def.globalData.appVersion;
    },
    invokeGlobalMethod() {
      this.$app.$def.globalMethod();
    },
    getAppVersion() {
      this.appVersion = this.$app.$def.globalData.appVersion;
    }
  }
  ```

- 页面对象
  | 属性 | 类型 | 描述 |
  | -------- | -------- | -------- |
  | data | Object/Function | 页面的数据模型,类型是对象或者函数,如果类型是函数,返回值必须是对象。属性名不能以$或_开头,不要使用保留字for,&nbsp;if,&nbsp;show,&nbsp;tid。<br/>data与private和public不能重合使用。 |
  | $refs | Object | 持有注册过ref&nbsp;属性的DOM元素或子组件实例的对象。示例见[获取DOM元素](#获取dom元素)。 |
  | private | Object | 页面的数据模型,private下的数据属性只能由当前页面修改。 |
  | public | Object | 页面的数据模型,public下的数据属性的行为与data保持一致。 |
  | props | Array/Object | props用于组件之间的通信,可以通过&lt;tag&nbsp;xxxx='value'&gt;方式传递给组件;props名称必须用小写,不能以$或_开头,不要使用保留字for,&nbsp;if,&nbsp;show,&nbsp;tid。目前props的数据类型不支持Function。示例见[自定义组件](../reference/arkui-js/js-components-custom-props.md)。 |
  | computed | Object | 用于在读取或设置进行预先处理,计算属性的结果会被缓存。计算属性名不能以$或_开头,不要使用保留字。示例见[自定义组件](../reference/arkui-js/js-components-custom-props.md)。 |

## 方法

- 数据方法
  | 方法 | 参数 | 描述 |
  | -------- | -------- | -------- |
  | $set | key:&nbsp;string,&nbsp;value:&nbsp;any | 添加新的数据属性或者修改已有数据属性。<br/>用法:<br/>this.$set('key',value):添加数据属性。 |
  | $delete | key:&nbsp;string | 删除数据属性。<br/>用法:<br/>this.$delete('key'):删除数据属性。 |

  示例代码

  ```
  // index.js
  export default {
    data: {
      keyMap: {
        OS: 'OpenHarmony',
        Version: '2.0',
      },
    },
    getAppVersion() {
      this.$set('keyMap.Version', '3.0');
      console.info("keyMap.Version = " + this.keyMap.Version); // keyMap.Version = 3.0
  
      this.$delete('keyMap');
      console.info("keyMap.Version = " + this.keyMap); // log print: keyMap.Version = undefined
    }
  }
  ```

- 公共方法
  | 方法 | 参数 | 描述 |
  | -------- | -------- | -------- |
  | $element | id:&nbsp;string | 获得指定id的组件对象,如果无指定id,则返回根组件对象。示例见[获取DOM元素](#获取dom元素)<br/>用法:<br/>&lt;div&nbsp;id='xxx'&gt;&lt;/div&gt;<br/>-&nbsp;this.$element('xxx'):获得id为xxx的组件对象。<br/>-&nbsp;this.$element():获得根组件对象。 |
  | $rootElement | 无 | 获取根组件对象。<br/>用法:this.$rootElement().scrollTo({&nbsp;duration:&nbsp;500,&nbsp;position:&nbsp;300&nbsp;}),&nbsp;页面在500ms内滚动300px。 |
  | $root | 无 | 获得顶级ViewModel实例。[获取ViewModel](#获取viewmodel)示例。 |
  | $parent | 无 | 获得父级ViewModel实例。[获取ViewModel](#获取viewmodel)示例。 |
  | $child | id:&nbsp;string | 获得指定id的子级自定义组件的ViewModel实例。[获取ViewModel](#获取viewmodel)示例。<br/>用法:<br/>this.$child('xxx')&nbsp;:获取id为xxx的子级自定义组件的ViewModel实例。 |

- 事件方法
  | 方法 | 参数 | 描述 |
  | -------- | -------- | -------- |
  | $watch | data:&nbsp;string,&nbsp;callback:&nbsp;string&nbsp;\|&nbsp;Function | 观察data中的属性变化,如果属性值改变,触发绑定的事件。示例见[自定义组件](../reference/arkui-js/js-components-custom-props.md)<br/>用法:<br/>this.$watch('key',&nbsp;callback) |

- 页面方法
  | 方法 | 参数 | 描述 |
  | -------- | -------- | -------- |
  | scrollTo<sup>6+</sup> | scrollPageParam: ScrollPageParam | 将页面滚动到目标位置,可以通过ID选择器指定或者滚动距离指定。 |

  **表1** ScrollPageParam<sup>6+</sup>
  
  | 名称 | 类型 | 默认值 | 描述 |
  | -------- | -------- | -------- | -------- |
  | position | number | - | 指定滚动位置。 |
  | id | string | - | 指定需要滚动到的元素id。 |
  | duration | number | 300 | 指定滚动时长,单位为毫秒。 |
  | timingFunction | string | ease | 指定滚动动画曲线,可选值参考<br/>[动画样式animation-timing-function](../reference/arkui-js/js-components-common-animation.md)。 |
  | complete | ()&nbsp;=&gt;&nbsp;void | - | 指定滚动完成后需要执行的回调函数。 |

  示例:

  ```
  this.$rootElement().scrollTo({position: 0})
  this.$rootElement().scrollTo({id: 'id', duration: 200, timingFunction: 'ease-in', complete: ()=>void})
  ```


## 获取DOM元素

1. 通过$refs获取DOM元素
   ```
   <!-- index.hml -->
   <div class="container">
     <image-animator class="image-player" ref="animator" images="{{images}}" duration="1s" onclick="handleClick"></image-animator>
   </div>
   ```

   ```
   // index.js
   export default {
     data: {
       images: [
         { src: '/common/frame1.png' },
         { src: '/common/frame2.png' },
         { src: '/common/frame3.png' },
       ],
     },
     handleClick() {
       const animator = this.$refs.animator; // 获取ref属性为animator的DOM元素
       const state = animator.getState();
       if (state === 'paused') {
         animator.resume();
       } else if (state === 'stopped') {
         animator.start();
       } else {
         animator.pause();
       }
     },
   };
   ```

2. 通过$element获取DOM元素
   ```
   <!-- index.hml -->
   <div class="container">
     <image-animator class="image-player" id="animator" images="{{images}}" duration="1s" onclick="handleClick"></image-animator>
   </div>
   ```

   ```
   // index.js
   export default {
     data: {
       images: [
         { src: '/common/frame1.png' },
         { src: '/common/frame2.png' },
         { src: '/common/frame3.png' },
       ],
     },
     handleClick() {
       const animator = this.$element('animator'); // 获取id属性为animator的DOM元素
       const state = animator.getState();
       if (state === 'paused') {
         animator.resume();
       } else if (state === 'stopped') {
         animator.start();
       } else {
         animator.pause();
       }
     },
   };
   ```

## 获取ViewModel

根节点所在页面:

```
<!-- root.hml -->
<element name='parentComp' src='../../common/component/parent/parent.hml'></element>
<div class="container">
  <div class="container">
    <text>{{text}}</text>
    <parentComp></parentComp>
  </div>
</div>
```

```
// root.js
export default {
  data: {
    text: 'I am root!',
  },
}
```

自定义parent组件:

```
<!-- parent.hml -->
<element name='childComp' src='../child/child.hml'></element>
<div class="item" onclick="textClicked">
  <text class="text-style" onclick="parentClicked">parent component click</text>
  <text class="text-style" if="{{show}}">hello parent component!</text>
  <childComp id = "selfDefineChild"></childComp>
</div>
```

```
// parent.js
export default {
  data: {
    show: false,
    text: 'I am parent component!',
  },
  parentClicked () {
    this.show = !this.show;
    console.info('parent component get parent text');
    console.info(`${this.$parent().text}`);
    console.info("parent component get child function");
    console.info(`${this.$child('selfDefineChild').childClicked()}`);
  },
}
```

自定义child组件:

```
<!-- child.hml -->
<div class="item" onclick="textClicked">
  <text class="text-style" onclick="childClicked">child component clicked</text>
  <text class="text-style" if="{{show}}">hello child component</text>
</div>
```

```
// child.js
export default {
  data: {
    show: false,
    text: 'I am child component!',
  },
  childClicked () {
    this.show = !this.show;
    console.info('child component get parent text');
    console.info('${this.$parent().text}');
    console.info('child component get root text');
    console.info('${this.$root().text}');
  },
}
```