Anthony Fu @ antfu.me

Vue3使用function*{}实现瀑布流

Mar 23 · 10min

JavaScript

Function* 生成器函数


简介

function* 声明创建一个绑定到给定名称的新生成器函数。生成器函数可以退出,并在稍后重新进入,其上下文(变量绑定)会在重新进入时保存。

MDN定义

代码实例 Vue3

Template and CSS

 <div class="content">
   <div class="list" ref="l1">
     <TransitionGroup name="add">
       <div class="item" v-for="(i1, index1) in list1" :key="index1">{{ i1.text }}</div>
     </TransitionGroup>
   </div>
   <div class="list" ref="l2">
     <TransitionGroup name="add">
       <div class="item" v-for="(i2, index2) in list2" :key="index2">{{ i2.text }}</div>
     </TransitionGroup>
   </div>
 </div>
  


<style scoped>
.add-move,
/* 对移动中的元素应用的过渡 */
.add-enter-active,
.add-leave-active {
  transition: all 1.5s ease;
}

.add-enter-from,
.add-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

/* 确保将离开的元素从布局流中删除
  以便能够正确地计算移动的动画。 */
.add-leave-active {
  position: absolute;
}

.content {
  width: 500px;
  display: flex;
  justify-content: space-around;
  align-items: flex-start;
}

.list {
  width: 240px;
}

.item {
  margin-bottom: 10px;
  width: 100%;
  padding: 20px;
  background-color: #EEE;
  border-radius: 20px;
  box-sizing: border-box;
}
</style>

Script

import { onMounted, ref, watch } from 'vue';

interface Data {
  text: string
}

const data = ref<Data[]>([
  { text: 'this is text,this is text,this is text,this is text,this is text,this is text,this is text,this is text,this is text,' },
  { text: 'this is text,this is text,this is text,this is text,this is text' },
  { text: 'this is text,this is text,this is text,this is text,this is text,this is text,this is text,this is text,this is text,' },
  { text: 'this is text,this is text,this is text,this is text,this is text' },
  { text: 'this is text,this is text,this is text,this is text,this is text,this is text,this is text,this is text,this is text,' },
  { text: 'this is text' },
  { text: 'this is text' },
  { text: 'this is text,this is text,this is text,this is text,this is text,this is text' },
  { text: 'this is text,this is text,this is text,this is text' },
  { text: 'this is text,this is text' },
])

const i = ref(0)
const list1 = ref<Data[]>([])
const list2 = ref<Data[]>([])
const l1 = ref()
const l2 = ref()

function* addData() {
  if (i.value != data.value.length) {
    if (l1.value.offsetHeight <= l2.value.offsetHeight) {
      yield list1.value.push(data.value[i.value++])
    } else {
      yield list2.value.push(data.value[i.value++])
    }
  }
}

watch(i, () => {
  console.log(l1.value.offsetHeight, l2.value.offsetHeight)
  setTimeout(() => {
    addData().next()
  }, 350);
})

onMounted(() => {
  addData().next()
})
>