``uni-app`` 在发布到H5时支持所有vue的语法;发布到App和小程序时,由于平台限制,无法实现全部vue语法,但``uni-app``仍是是对vue语法支持度最高的跨端框架。本文将详细讲解差异。
相比Web平台, ``Vue.js`` 在 ``uni-app`` 中使用差异主要集中在两个方面:
- 新增:uni-app除了支持Vue实例的生命周期,还支持应用启动、页面显示等生命周期
- 受限:相比web平台,在小程序和App端部分功能受限,具体见下。
- v3版本App端可以使用更多的vue特性,[详见](https://ask.dcloud.net.cn/article/36599)
## 生命周期
``uni-app`` 完整支持 ``Vue`` 实例的生命周期,同时还新增 [应用生命周期](/frame?id=应用生命周期) 及 [页面生命周期](/frame?id=页面生命周期)。
详见Vue官方文档:[生命周期钩子](https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90)。
## 模板语法
``uni-app`` 完整支持 ``Vue`` 模板语法。
详见Vue官方文档:[模板语法](https://cn.vuejs.org/v2/guide/syntax.html)。
**注意**
如果使用**老版**的非自定义组件模式,即manifest中`"usingComponents":false`,部分模版语法不支持,但此模式已于2019年11月起下线。
## data 属性
``data`` 必须声明为返回一个初始数据对象的函数(注意函数内返回的数据对象不要直接引用函数外的对象);否则页面关闭时,数据不会自动销毁,再次打开该页面时,会显示上次数据。
```javascript
//正确用法,使用函数返回对象
data() {
return {
title: 'Hello'
}
}
//错误写法,会导致再次打开页面时,显示上次数据
data: {
title: 'Hello'
}
//错误写法,同样会导致多个组件实例对象数据相互影响
const obj = {
title: 'Hello'
}
data() {
return {
obj
}
}
```
### 注意事项
* 由于小程序端不支持更新属性值为 undefined,框架内部将替换 undefined 为 null,此时可能出现预期之外的情况([相关反馈](https://github.com/dcloudio/uni-app/issues/1460)),需要自行判断一下。
## 全局变量
实现全局变量的方式需要遵循 Vue 单文件模式的开发规范。详细参考:[uni-app全局变量的几种实现方式](https://ask.dcloud.net.cn/article/35021)
## 其他配置
Vue 组件编译到小程序平台的时候会编译为对应平台的组件,部分小程序平台支持 options 选项(具体选项参考对应小程序平台文档的自定义组件部分),一般情况默认即可,如有特殊需求可在 Vue 组件中增加 options 属性。
```js
export default {
props: ['data'],
options: {
multipleSlots: false,// 在微信小程序中关闭当前组件的多slot支持,默认启用
virtualHost: true // 在微信小程序中将组件节点渲染为虚拟节点,更加接近Vue组件的表现
}
}
```
## Class 与 Style 绑定
为节约性能,我们将 ``Class`` 与 ``Style`` 的表达式通过 ``compiler`` 硬编码到 ``uni-app`` 中,支持语法和转换效果如下:
class 支持的语法:
```html
111
222
333
444
555
```
style 支持的语法:
```html
666
777
```
非H5端不支持 [Vue官方文档:Class 与 Style 绑定](https://cn.vuejs.org/v2/guide/class-and-style.html) 中的 ``classObject`` 和 ``styleObject`` 语法。
不支持示例:
```html
```
**注意:以``:style=""``这样的方式设置px像素值,其值为实际像素,不会被编译器转换。**
此外还可以用 ``computed`` 方法生成 ``class`` 或者 ``style`` 字符串,插入到页面中,举例说明:
```html
```
**用在组件上**
非H5端(非自定义组件编译模式)暂不支持在自定义组件上使用 ``Class`` 与 ``Style`` 绑定
## 计算属性
完整支持 [Vue官方文档:计算属性](https://cn.vuejs.org/v2/guide/computed.html)。
## 条件渲染
完整支持 [Vue官方文档:条件渲染](https://cn.vuejs.org/v2/guide/conditional.html)
## 列表渲染
完整vue列表渲染 [Vue官方文档:列表渲染](https://cn.vuejs.org/v2/guide/list.html)
### key
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 ```` 中的输入内容,```` 的选中状态),需要使用 ``:key`` 来指定列表中项目的唯一的标识符。
``:key`` 的值以两种形式提供
- 使用 ``v-for`` 循环 ``array`` 中 ``item`` 的某个 ``property``,该 ``property`` 的值需要是列表中唯一的字符串或数字,且不能动态改变。
- 使用 ``v-for`` 循环中 ``item`` 本身,这时需要 ``item`` 本身是一个唯一的字符串或者数字
当数据改变触发渲染层重新渲染的时候,会校正带有 ``key`` 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
**如不提供 ``:key``,会报一个 ``warning``, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。**
**示例:**
```html
{{index +':'+ item.name}}
{{index +':'+ item}}
```
### 注意事项
* 在H5平台 使用 v-for 循环整数时和其他平台存在差异,如 `v-for="(item, index) in 10"` 中,在H5平台 item 从 1 开始,其他平台 item 从 0 开始,可使用第二个参数 index 来保持一致。
* 在非H5平台 循环对象时不支持第三个参数,如 `v-for="(value, name, index) in object"` 中,index 参数是不支持的。
* 小程序端数据为差量更新方式,由于小程序不支持删除对象属性,使用的设置值为 null 的方式替代,导致遍历时可能出现不符合预期的情况,需要自行过滤一下值为 null 的数据([相关反馈](https://ask.dcloud.net.cn/question/103269))。
## 事件处理器
几乎全支持 [Vue官方文档:事件处理器](https://cn.vuejs.org/v2/guide/events.html)
```javascript
// 事件映射表,左侧为 WEB 事件,右侧为 ``uni-app`` 对应事件
{
click: 'tap',
touchstart: 'touchstart',
touchmove: 'touchmove',
touchcancel: 'touchcancel',
touchend: 'touchend',
tap: 'tap',
longtap: 'longtap', //推荐使用longpress代替
input: 'input',
change: 'change',
submit: 'submit',
blur: 'blur',
focus: 'focus',
reset: 'reset',
confirm: 'confirm',
columnchange: 'columnchange',
linechange: 'linechange',
error: 'error',
scrolltoupper: 'scrolltoupper',
scrolltolower: 'scrolltolower',
scroll: 'scroll'
}
```
**注意:**
* 为兼容各端,事件需使用 ``v-on`` 或 ``@`` 的方式绑定,请勿使用小程序端的``bind`` 和 ``catch`` 进行事件绑定。
* 事件修饰符
* ``.stop``:各平台均支持, 使用时会阻止事件冒泡,在非 H5 端同时也会阻止事件的默认行为
* ``.native``:监听原生事件,仅在 H5 平台支持
* ``.prevent`` 仅在 H5 平台支持
* ``.self``:仅在 H5 平台支持
* ``.once``:仅在 H5 平台支持
* ``.capture``:仅在 H5 平台支持
* ``.passive``:仅在 H5 平台支持
* 若需要禁止蒙版下的页面滚动,可使用 ``@touchmove.stop.prevent="moveHandle"``,moveHandle 可以用来处理 touchmove 的事件,也可以是一个空函数。
```html
```
* 按键修饰符:``uni-app``运行在手机端,没有键盘事件,所以不支持按键修饰符。
## 表单控件绑定
支持 [Vue官方文档:表单控件绑定](https://cn.vuejs.org/v2/guide/forms.html)。
建议开发过程中直接使用 [uni-app:表单组件](component/button)。用法示例:
H5 的select 标签用 picker 组件进行代替
```html
当前选择:{{array[index]}}
```
表单元素 radio 用 radio-group 组件进行代替
```html
```
## v-html指令
App端(vue页面[V3编译模式](https://ask.dcloud.net.cn/article/36599))和H5端支持v-html,其他端不支持v-html。
跨端的富文本处理方案详见:[https://ask.dcloud.net.cn/article/35772](https://ask.dcloud.net.cn/article/35772)
## 组件
### Vue 组件
组件是 ``vue`` 技术中非常重要的部分,组件使得与ui相关的轮子可以方便的制造和共享,进而使得vue使用者的开发效率大幅提升。
uni-app搭建了组件的插件市场,可大幅提升开发者的效率。[https://ext.dcloud.net.cn/](https://ext.dcloud.net.cn/)
在项目的/component目录下存放组件,在要显示组件的页面中则分为3步:导入、注册和使用。
可以这个[评分组件](https://ext.dcloud.net.cn/plugin?id=33)的使用为例,了解vue组件的使用方式。
```html
```
- `2.5.0+`版本支持在pages.json内引入组件,[详见](/collocation/pages?id=easycom)
- **uni-app只支持vue单文件组件(.vue 组件)**。其他的诸如:动态组件,自定义 ``render``,和``