前言
uni-app
在发布到 H5
时,是支持所有 vue
的语法的。但是发布到App或者小程序时,由于各个平台等限制,无法实现全部 vue
语法,本文将详细讲解差异。
相比Web平台, Vue.js
在 uni-app
中使用差异主要集中在两个方面:
新增:uni-app除了支持Vue实例的生命周期,还支持应用启动、页面显示等生命周期
受限:相比web平台,在小程序和App端部分功能受限,具体见下。
生命周期
uni-app
在支持完整 Vue
实例的生命周期上,同时还新增 应用生命周期 及 页面生命周期。
详见Vue官方文档:生命周期钩子。
应用生命周期包括下列函数
1、onLaunch 当uni-app 初始化完成时触发(全局只触发一次)
2、onShow 当 uni-app 启动,或从后台进入前台显示
3、onHide 当 uni-app 从前台进入后台
4、onUniNViewMessage 对 nvue 页面发送的数据进行监听
注意
(1)、应用生命周期仅可在App.vue中监听,在其它页面监听无效。
(2)、onlaunch里进行页面跳转,可能遇白屏报错,可以去官方查找解决方案。
页面生命周期
注意
(1)、onTabItemTap常用于点击当前tabitem,滚动或刷新当前页面。如果是点击不同的tabitem,一定会触发页面切换。
(2)、如果想在App端实现点击某个tabitem不跳转页面,不能使用onTabItemTap,可以使用plus.nativeObj.view放一个区块盖住原先的tabitem,并拦截点击事件。
(3)、onTabItemTap在App端,从HBuilderX 1.9 的自定义组件编译模式开始支持。
语法支持
支持的 vue 语法
1、支持过滤器 filter
2、支持比较复杂的 JavaScript 渲染表达式
3、支持在 template 内使用 methods 中的函数
4、支持 v-html (同 rich-text 的解析)
5、支持 v-slot 新语法
6、支持解构插槽 Prop 设置默认值
7、支持 slot 后备内容
8、组件支持原生事件绑定,如:@tap.native
不支持的 vue 语法
1、class不支持绑定Obejct变量(使用字符串的形式绑定)
2、不支持事件修饰符:prevent、passive(在App与小程序平台,使用stop修饰符,既可以阻止冒泡也能阻止默认行为)
3、不支持render、inline-template、X-Templates、keep-alive、transition
4、不支持使用 Vue.use 的方式注册全局组件(在main.js使用Vue.component的方式引入)
列表渲染
1、在H5平台 使用 v-for 循环整数时和其他平台存在差异,如 v-for="(ite`m, index) in 10" 中,在H5平台 item 从 1 开始,其他平台 item 从 0 开始,可使用第二个参数 index 来保持一致。
2、在非H5平台 循环对象时不支持第三个参数,如 v-for="(value, name, index) in object" 中,index 参数是不支持的。
事件处理
几乎全支持 事件处理器
// 事件映射表,左侧为 WEB 事件,右侧为 ``uni-app`` 对应事件
{
click: 'tap',
touchstart: 'touchstart',
touchmove: 'touchmove',
touchcancel: 'touchcancel',
touchend: 'touchend',
tap: 'tap',
longtap: 'longtap',
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'
}
注意:
1、为兼容各端,事件需使用 v-on 或 @ 的方式绑定,请勿使用小程序端的bind 和 catch 进行事件绑定。
2、事件修饰符
.stop
:各平台均支持, 使用时会阻止事件冒泡,在非 H5 端同时也会阻止事件的默认行为
.prevent
仅在 H5 平台支持
.self
:仅在 H5 平台支持
.once
:仅在 H5 平台支持
.capture
:仅在 H5 平台支持
.passive
:仅在 H5 平台支持
3、若需要禁止蒙版下的页面滚动,可使用 @touchmove.stop.prevent="moveHandle"
,moveHandle
可以用来处理 touchmove
的事件,也可以是一个空函数。
<view class="mask" @touchmove.stop.prevent="moveHandle"></view>
4、按键修饰符:uni-app
运行在手机端,没有键盘事件,所以不支持按键修饰符。
命名限制
在 uni-app 中以下这些作为保留关键字,不可作为组件名。
a
, canvas
, cell
, content
, countdown
, datepicker
, div
, element
, embed
, header
, image
, img
, indicator
, input
, link
, list
, loading-indicator
, loading
, marquee
, meta
, refresh
, richtext
, script
, scrollable
, scroller
, select
, slider-neighbor
, slider
, slot
, span
, spinner
, style
, svg
, switch
, tabbar
, tabheader
, template
, text
, textarea
, timepicker
, trisition-group
, trisition
, video
, view
, web
除以上列表中的名称外,标准的 HTML 及 SVG 标签名也不能作为组件名。
其他疑难杂症
1、如何获取上个页面传递的数据
在 onLoad 里得到,onLoad 的参数是其他页面打开当前页面所传递的数据。
2、如何捕获 app 的 onError
由于 onError 并不是完整意义的生命周期,所以只提供一个捕获错误的方法,在 app 的根组件上添加名为 onError 的回调函数即可。如下:
export default {
// 只有 app 才会有 onLaunch 的生命周期
onLaunch () {
// ...
},
// 捕获 app error
onError (err) {
console.log(err)
}
}
3、组件属性设置不生效解决办法
当重复设置某些属性为相同的值时,不会同步到view层。 例如:每次将scroll-view组件的scroll-top属性值设置为0,只有第一次能顺利返回顶部。 这和props的单向数据流特性有关,组件内部scroll-top的实际值改动后,其绑定的属性并不会一同变化。
解决办法有两种(以scroll-view组件为例):
(1)、监听scroll事件,记录组件内部变化的值,在设置新值之前先设置为记录的当前值
<scroll-view :scroll-top="scrollTop" scroll-y="true" @scroll="scroll">
<script>
export default {
data() {
return {
scrollTop: 0,
old: {
scrollTop: 0
}
}
},
methods: {
scroll: function(e) {
this.old.scrollTop = e.detail.scrollTop
},
goTop: function(e) {
this.scrollTop = this.old.scrollTop
this.$nextTick(function() {
this.scrollTop = 0
});
}
}
}
</script>
(2)、监听scroll事件,获取组件内部变化的值,实时更新其绑定值
<scroll-view :scroll-top="scrollTop" scroll-y="true" @scroll="scroll">
<script>
export default {
data() {
return {
scrollTop: 0,
}
},
methods: {
scroll: function(e) {
this.scrollTop = e.detail.scrollTop
},
goTop: function(e) {
this.scrollTop = 0
}
}
}
</script>
第二种解决方式在某些组件可能造成抖动,推荐第一种解决方式。