looplan-touch
v1.1.9
Published
触控操作组件
Downloads
11
Readme
Looplan Touch 触控库
Looplan Touch 是一个以 Vue3 + TypeScript 为基础的触控交互库,提供组件与方法用来实现拖拽、排序与跨组转移等交互能力。核心设计通过统一事件绑定和插件机制扩展触摸事件行为,适配表格、列表与栅格等多种布局场景。
安装
npm i looplan-touch引入
import { LpDraggable, useSortable } from 'looplan-touch'组件与方法
LpDraggable:拖拽组件,支持同组排序与跨组转移,内置过渡适配与预览态占位useSortable(target, list, option):对现有 DOM 列表开启排序能力(例如表格tr行),适配过渡与方向
示例一:跨组拖动(组件)
模板:
<template>
<div class="group-container">
<div class="group">
<h4>列表 A1</h4>
<lp-draggable v-model="listA1" group="group-a" :allow-groups="['group-b']">
<template #item="{ item, index }">
<div class="custom-item group-a-item">
<span class="item-icon">📋</span>
<span class="item-text">{{ item.name }}</span>
<span class="item-badge">A1-{{ index }}</span>
</div>
</template>
</lp-draggable>
</div>
<div class="group">
<h4>列表 A2</h4>
<lp-draggable v-model="listA2" group="group-a" :allow-groups="['group-b']">
<template #item="{ item, index }">
<div class="custom-item group-a-item">
<span class="item-icon">📊</span>
<span class="item-text">{{ item.name }}</span>
<span class="item-badge">A2-{{ index }}</span>
</div>
</template>
</lp-draggable>
</div>
</div>
</template>脚本:
import { ref } from 'vue'
import { LpDraggable } from 'looplan-touch'
const listA1 = ref([
{ name: '任务 A1-1' },
{ name: '任务 A1-2' },
{ name: '任务 A1-3' }
])
const listA2 = ref([
{ name: '任务 A2-1' },
{ name: '任务 A2-2' },
{ name: '任务 A2-3' },
{ name: '任务 A2-4' }
])样式(简要):
.group-container { display: grid; gap: 20px }
.group { border: 2px solid #e9ecef; border-radius: 8px; padding: 16px }
.custom-item { display:flex; align-items:center; gap:12px; padding:12px; margin:8px 0; user-select:none }LpDraggable Props
v-model: 列表数据(数组)group: 分组名称,用于跨组识别allow-groups: 允许接收的分组名数组direction: 元素分布方向(x | y | xy | auto,默认auto)
LpDraggable 插槽
#item="{ item, index }":自定义子项渲染
示例二:表格排序(useSortable)
模板:
<template>
<div ref="tableRef" class="test-table1">
<lp-table :data="tableData" :columns="columns" row-key="id" row-transition-name="lp-drag-transition">
<template #column.sort="{ item }">
<div class="sort-field"><lp-icon is="sorting"></lp-icon></div>
</template>
<!-- 其它列略 -->
</lp-table>
</div>
</template>脚本:
import { ref, onMounted, useTemplateRef, onUnmounted } from 'vue'
import { useSortable } from 'looplan-touch'
const tableRef = useTemplateRef('tableRef')
const tableData = ref([
{ id: 1, name: '张三', age: 18 },
{ id: 2, name: '李四', age: 19 },
{ id: 3, name: '王五', age: 20 }
])
let touchBox
onMounted(() => {
({ touchBox } = useSortable(tableRef, tableData, {
targetClass: 'lp-table__tr',
dragClass: 'sort-field',
transitionName: 'lp-drag-transition',
direction: 'auto'
}))
})
onUnmounted(() => { touchBox.unbindEvent() })useSortable Option
targetClass: 被排序的行元素类名(如lp-table__tr)dragClass: 触发拖动的类名(如排序列里的图标容器)transitionName: 过渡动画前缀(如lp-drag-transition),用于检测过渡期间的碰撞过滤idKey: 元素 id 键名(可选)direction: 布局方向(x | y | xy | auto)onMove(params): 移动回调(可选)
示例三:同组排序(useSortable,跨两列)
模板:
<div ref="list1Ref" class="list drag-list">
<transition-group name="lp-list-transition">
<div class="custom-item lp-sortable__item" v-for="item in listA1" :key="item.id">{{ item.name }}</div>
</transition-group>
</div>
<div ref="list2Ref" class="list drag-list">
<transition-group name="lp-list-transition">
<div class="custom-item lp-sortable__item" v-for="item in listA2" :key="item.id">{{ item.name }}</div>
</transition-group>
</div>脚本:
import { ref, useTemplateRef, onUnmounted } from 'vue'
import { useSortable } from 'looplan-touch'
const listA1 = ref([{ id:'A1-1', name:'任务 A1-1' }, { id:'A1-2', name:'任务 A1-2' }])
const listA2 = ref([{ id:'A2-1', name:'任务 A2-1' }, { id:'A2-2', name:'任务 A2-2' }])
const listRef1 = useTemplateRef('list1Ref')
const listRef2 = useTemplateRef('list2Ref')
const { touchBox: tb1 } = useSortable(listRef1, listA1, {
targetClass: 'lp-sortable__item',
transitionName: 'lp-list-transition'
})
const { touchBox: tb2 } = useSortable(listRef2, listA2, {
targetClass: 'lp-sortable__item',
transitionName: 'lp-list-transition'
})
onUnmounted(() => { tb1.unbindEvent(); tb2.unbindEvent() })行为与适配
- 过渡适配:
transition-group在tr行过渡时不添加类名,库通过检测transform来过滤过渡元素命中 - 命中解析:表格中拖动命中
td/th时向上寻找对应tr行作为目标 - 方向适配:
direction: auto会根据容器flex-direction与flex-wrap推断为x/y/xy - 尾部插入:
computeIndexByPoint会在指针位于最后一项之后(y 轴底部 / x 轴右侧 / xy 右下)返回index + 1
许可
MIT
