现象
单个元素使用v-if时,不会有抖动的问题,但是用在组件上,尤其是组件的布局稍微复杂点,用v-if的话,会出现组件出现之后,内部的元素有一个很短暂的位置调整的现象,估计是和weex的实现机制有关。这里暂且不深究,只是给出一个解决方案来避免这个问题。
解药
组件的第一次构造使用v-if,后续的显示和隐藏则使用自定义的属性来控制,然后在组件内部观察该属性,根据属性值变化来设置组件根元素的visibility。
另外,组件初次被构造时,根元素的visibility默认为hidden,在mounted回调时才改为visible,这样就可以避免出现抖动了。
PS:因为weex只支持单类名选择器,而不支持属性选择器,所以vue的v-cloak指令无法使用
补充
如果v-if内有多个元素,那么视觉上是元素先出现,再调整到设定位置的过程。所以对v-if的元素进行动画设置的时候一定要小心,一定要确保其到位之后再设置动画,否则动画要么没有运行(在v-if为true那一刻设置动画,但是此时dom还没有刷新),要么动画效果不对(v-if内的元素已创建,但是还没调整到位,要到下一帧才行)。建议使用visibility来控制
代码
组件的必要代码:
<template>
<div :style="{ visibility: componentVisibility }">
...
</div>
</template>
<script>
export default {
props: [ 'show' ],
data() {
return {
componentVisibility: 'hidden'
}
},
watch: {
show(val) {
this.componentVisibility = val ? 'visible' : 'hidden'
}
},
mounted() {
this.show && (this.componentVisibility = 'visible');
}
}
</script>
外部使用组件的代码示例:
<template>
<mycomponent v-if="createMyComponent" :show="myComponentVisible"></mycomponent>
</template>
<script>
export default {
data() {
return {
createMyComponent: false,
myComponentVisible: false
}
}
methods: {
showMyComponent(visible) {
if (visible && !this.createMyComponent) {
this.createMyComponent = true;
}
this.myComponentVisible = visible?true:false;
}
}
}
</script>