列表排序应用FLIP动画(vue)
生活随笔
收集整理的這篇文章主要介紹了
列表排序应用FLIP动画(vue)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
效果
原理詳解
鏈接
1.beforeUpdate 獲取first 變化前位置 (以id建立map映射)
2.updated 獲取變化后位置 last
3.禁用transition并transform元素回初始位置
4.異步恢復transition 并取消 transform
代碼
<template><div ref="container"><div style="display: flex"><div style="width:400px"><!--僅展示三級數據,若需遞歸自行修改--><div class="item" :id="i.value" v-for="i in locArr" :key="i.value"><div>{{i.label}}</div><div class="item" :id="j.value" v-for="j in i.children" :key="j.value"><div>{{j.label}}</div><div class="item" :id="k.value" v-for="k in j.children" :key="k.value"><div>{{k.label}}</div></div></div></div></div><div style="padding: 10px"><button @click="shuffle">重新隨機數據</button><button @click="shuffleOne">打亂一級順序</button><button @click="shuffleTwo">打亂二級順序</button></div></div></div> </template><script> /* 1.beforeUpdate 獲取first 變化前位置 (以id建立map映射), 2.updated 獲取變化后位置 last , 3.禁用transition并transform元素回初始位置, 4.異步恢復transition 并取消 transform *//*** 亂序數組*/ Array.prototype.shuffle = function () {let input = this;for (let i = input.length - 1; i >= 1; i--) {let ri = ~~(Math.random() * (i + 1));input[i] = [input[ri], input[ri] = input[i]][0];}return input; };/*** 隨機多級數據* @param root* @param len* @param level*/ const treeOptions = ({ root = '0', len = 40, level = 4 }) => {let levelPoolLen = level, originPoolLen = len - levelPoolLen//創建 level 個 LevelPool ,并為每個 LevelPool 初始化一個元素let levelPool = []for (let i = 1; i <= levelPoolLen; i++) {levelPool.push([{ id: '', parentId: root, label: '', value: '' }])}//初始化指定數量的元素并隨機丟入 LevelPool 中for (let i = 0; i < originPoolLen; i++) {let currLevel = ~~(Math.random() * level)levelPool[currLevel].push({ id: '', parentId: root, label: '', value: '' })}let nextId = 0//由前到后依次遍歷LevelPool,遍歷本級池中各項并隨機從前一級池中選取一項作為當前項的父級for (let i = 0, item; (item = levelPool[0][i]) != null; i++) {item.id = ++nextIditem.parentId = rootitem.label = `label${item.id}`item.value = `value${item.id}`item.level = 0}for (let i = 1; i < levelPoolLen; i++) {let prevLevelPool = levelPool[i - 1]let prevLevelPoolLen = prevLevelPool.lengthfor (let j = 0, item; (item = levelPool[i][j]) != null; j++) {//隨機父節點let parent = prevLevelPool[~~(Math.random() * prevLevelPoolLen)]if (!parent.children) {parent.children = []}item.id = `${parent.id}-${parent.children.length}`item.parentId = parent.iditem.label = `label${item.id}`item.value = `value${item.id}`item.level = iparent.children.push(item)}}//將一級levelPool合并輸出return levelPool[0] }let firstMap = [], last = [] export default {name: "FLIP",data() {return {locArr: treeOptions({ level: 3, len: 40 })}},beforeUpdate() {this.$refs.container.querySelectorAll('.item').forEach(d => firstMap[d.id] = d.getBoundingClientRect())},updated() {let lastRect, firstRect, transX, transY, $lastNodes = this.$refs.container.querySelectorAll('.item')$lastNodes.forEach(d => {lastRect = d.getBoundingClientRect()firstRect = firstMap[d.id]if (firstRect) {transX = firstRect.left - lastRect.lefttransY = firstRect.top - lastRect.topd.style.transition = 'none'd.style.transform = `translate3D(${transX}px,${transY}px,0) `}})setTimeout(_ => {$lastNodes.forEach(d => {d.style.transition = ''d.style.transform = ''})})},methods: {shuffle() {// this.locArr[1].children.push( this.locArr.shift())this.locArr = treeOptions({ level: 3, len: 40 })},shuffleOne() {this.locArr = [...this.locArr.shuffle()]},shuffleTwo() {const vm = thisthis.locArr.forEach((d, index) => {if (d.children) {d.children = [...d.children.shuffle()]}})}} } </script><style scoped>.item {transition: all 1s;margin-left: 20px;}.item>div:not(.item){padding:5px;border-radius:2px;background: #fff;box-shadow: #999999 2px 2px 5px 1px;}button{display: block;margin: 10px;cursor: pointer;} </style>總結
以上是生活随笔為你收集整理的列表排序应用FLIP动画(vue)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python pyqt5 线程 暂停 重
- 下一篇: centos安装mysql5.6系统崩溃