Vue3基础组件开发之穿梭框

318 阅读2分钟

穿梭框组件通常用于在两个列表之间进行数据的选择和移动。它包含两个列表,左侧列表显示待选择的数据,右侧列表显示已选择的数据。用户可以通过点击按钮或拖拽操作,将数据从左侧列表移动到右侧列表,或者从右侧列表移动到左侧列表

Vue3中实现穿梭框组件可以使用<teleport><transition>组件来实现。

使用ref来声明了两个响应式变量sourceListtargetList,分别表示待选列表和已选列表。

通过v-for指令将列表渲染到页面上,并且通过@click事件监听点击事件。当点击待选列表中的项时,将该项从待选列表中移除,并添加到已选列表中;当点击已选列表中的项时,将该项从已选列表中移除,并添加到待选列表中。

Vue3中使用<teleport><transition>组件来实现移动效果:

<template>
  <div class="transfer">
    <div class="transfer-panel">
      <h2>待选列表</h2>
      <ul>
        <li v-for="item in sourceList" :key="item.id" @click="moveToTarget(item)">
          {{ item.name }}
        </li>
      </ul>
    </div>
    <div class="transfer-panel">
      <h2>已选列表</h2>
      <ul>
        <li v-for="item in targetList" :key="item.id" @click="moveToSource(item)">
          {{ item.name }}
        </li>
      </ul>
    </div>
    <transition name="fade">
      <div v-if="movingItem" class="moving-item" :key="movingItem.id">
        {{ movingItem.name }}
      </div>
   <transition>
  </div>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const sourceList = ref([
      { id: 1, name: 'Option 1' },
      { id: 2, name: 'Option 2' },
      { id: 3, name: 'Option 3' },
    ]);

    const targetList = ref([]);

    const movingItem = ref(null);

    const moveToTarget = (item) => {
      sourceList.value = sourceList.value.filter((i) => i.id !== item.id);
      targetList.value.push(item);
      movingItem.value = item;
      setTimeout(() => {
        movingItem.value = null;
      }, 500);
    };

    const moveToSource = (item) => {
      targetList.value = targetList.value.filter((i) => i.id !== item.id);
      sourceList.value.push(item);
      movingItem.value = item;
      setTimeout(() => {
        movingItem.value = null;
      }, 500);
    };

    return {
      sourceList,
      targetList,
      movingItem,
      moveToTarget,
      moveToSource,
    };
  },
};
</script>

<style>
.transfer {
  display: flex;
  justify-content: space-between;
}

.transfer-panel {
  width: 200px;
  border: 1px solid #ccc;
  padding: 10px;
}

.transfer-panel h2 {
  margin-top: 0;
}

.transfer-panel ul {
  list-style: none;
  padding: 0;
}

.transfer-panel li {
  cursor: pointer;
  margin-bottom: 5px;
}

.moving-item {
  position: absolute;
  background-color: #f2f2f2;
  padding: 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
  opacity: 0;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}
</style>

使用<transition>组件包裹了一个<div>元素,通过设置name属性和相应的样式类名来实现渐入渐出的效果。在移动元素时,将要移动的元素赋值给movingItem变量,并在<div>元素中显示出来,然后通过``函数将movingItem变量置为null,以实现渐出效果。