vue(uni-app)中v-if与动画效果冲突的解决办法

这两天终于真正接触到了uni-app——其实就是一款基于vue的多端融合产品,它可以调用任意平台的api,以达到“可以顺利登陆各平台”的目的。
写demo的时候遇到点麻烦:
由于使用了v-if条件判断,所以元素展示很“突兀”,定义的transform根本没有效果!


解决办法:

  1. 改用v-show
  2. 使用$nextTick() + setTimeout() 方法:

css:

.create-content{
	position:fixed;
	/* ... */
	transition:all .3s;
	opacity:0;
	transform:scale(0) translateY(200%);
}
.create__show{
	opacity:1;
	transform:scale(1) translateY(0);
}

index.vue:

<view v-if="active" class="create-content" :class="{'create__show':textShow}">
	
</view>

js:

methods:{
	create(){
		this.active=true
		this.$nextTick(()=>{
			setTimeout(()=>{
				this.textShow=true
			},50)
		})
	},
	//...
}

$nextTick() 的用法:

Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.thenMessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0)代替。

所以,关于这个api的使用,有一下几点“规定”:

  • 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中

created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。

  • 在数据变化后要执行的某个操作,而这个操作需要使用随数据改变而改变的DOM结构的时候,这个操作都应该放进Vue.nextTick()的回调函数中。

实现一个简单的 $nextTick() 方法:

let callbacks=[];
let pending=false;
function nextTick(cb){
	callbacks.push(cb);
	if(!pending){
		pending=true;
		setTimeout(flushCallbacks,0);
	}
}
function flushCallback(){
	pending=false;
	const pipes=callbacks.slice(0);
	callbacks.length=0;
	for(let i=0;i<pipes.length;i++){
		pipes[i]();
	}
}

如何开启一个uni-app项目:

  • 在HBuilderX中,直接点击“创建项目”->“uni-app项目”即可
  • 在其他编译器如VSCode中,可以借助【cli工具】(命令行):vue create -p dcloudio/uni-preset-vue 项目名称,回车 选择“默认模板”即可
发布了195 篇原创文章 · 获赞 391 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_43624878/article/details/103980023