不良费你的时间 先说本文介绍的效果
根据传过来的数据 动态的给组件嵌套N层div
//正常循环效果 v-for 是并列循环
<div>
第一个
</div>
<div>
第二个
</div>
<div>
第三个
</div>
//想要达到的效果
<div data-name='第一层'>
<div data-name='第二层'>
<div data-name='第三层'>
</div>
</div>
</div>
大多数场景v-for 足以满足 多数用于循环列表把数据一条条的展示出来
今天碰到的场景是 用户自定义给模块添加动效 一个模块可以添加多个动效,但是多个动效作用于一个div上会被覆盖。想到的解决办法是每加一个动效就多包裹一层div 为每一个动效单独创建一层div最深层再包裹着目标组件
解决思路使用自定义指令 操作真实节点
//一个简版的指令demo
directives: {
replace:{
inserted:function(el, binding, vnode){
//获取该节点的上一级 不要去使用parentNode 再次更新触发指令时已经创建了外层包裹div 会影响
let parentEl = document.querySelector('.elpr'+binding.value.id);
//创建最外层div 形成一个单独的盒子
let divBox = document.createElement('div');
//获取到指令传递的参数
let info = binding.value.animate;
//接下来循环创建的div集合
let divList = [];
//如果没有参数代表不需要这个指令操作 阻止继续执行
//兼容数据更新的时候再次更新没有参数直接把目标节点插入并阻止继续运行
if(!parentEl) return null;
if(!info || Object.keys(info).length == 0){
parentEl.innerHTML = "";
parentEl.appendChild(el);
return null;
}
//开始循环参数
for(let x in info){
//每次循环创建空div
let divBoxlist = document.createElement('div');
//把对应的参数绑定到刚刚创建的div上
divBoxlist.style.animationDuration = info[x].animateTime+'s';
divBoxlist.style.animationDelay = info[x].animateDelay+'s';
divBoxlist.style.animationIterationCount = info[x].animateCount == 0 ? 'infinite' : info[x].animateCount;
divBoxlist.classList.add('animated');
divBoxlist.classList.add(info[x].animateName);
//参数绑定成功后把创建好的div保存进数组
divList.push(divBoxlist);
}
//把目标节点插入最后一个div 上
divList[divList.length-1].appendChild(el)
for(let a = divList.length -1; a >= 1; a--){
//倒叙循环创建好的div集合
//从后往前的一次把后面的div插入到前面的div
divList[a-1].appendChild( divList[a])
}
//最开始创建的最外层div盒子
divBox.appendChild(divList[0]);
//把最开始获取好的目标父节点内容清空 这里是应对每次更新的情况
parentEl.innerHTML = "";
//最后把一切都整理的div数据放入到目标父节点中
parentEl.appendChild(divBox);
}
}
}
网友评论