当前位置:网站首页>工作经验-组件封装(拖拽排序组件)
工作经验-组件封装(拖拽排序组件)
2022-08-09 21:54:00 【杨旬】
子组件``
<div id="box" :style="boxStyle">
<div v-for="item in modelValue" :key="item.id">
<slot :msg="item"></slot>
</div>
</div>
</template>
<script setup lang="ts">
import Sortable from "sortablejs";
import {
defineEmits,
defineProps,
nextTick,
onMounted,
defineExpose,
withDefaults,
computed,
} from "vue";
//内部interface type类型定义
interface IModelValue {
id: string;
index: number;
name: string;
}
type ILayout = "x" | "y" | "X" | "Y";
interface IProps {
modelValue: IModelValue[];
layout?: ILayout;
}
// props 定义:对外选项
const props = withDefaults(defineProps<IProps>(), {
layout: "x",
});
// emit 定义:自定义事件
const emits = defineEmits(["update:modelValue"]);
//computed定义:计算属性
const boxStyle = computed(() => {
if (props.layout == "y" || props.layout == "Y") {
return "flex-direction:column;height:100%;width:fit-content";
} else {
return "flex-direction:row;width:100%;height:fit-content";
}
});
//生命周期函数
onMounted(() => {
initDragAble();
});
//自定义函数
//初始化拖拽元素
function initDragAble() {
nextTick(() => {
const el = document.querySelector("#box");
const sortable = Sortable.create(el as HTMLElement, {
// 在拖拽过程中会有动画产生
animation: 150,
easing: "cubic-bezier(1, 0, 0, 1)",
// 是否可以进行拖拽排序,为 true 时,不能进行排序,函数不会被触发,为 false 时, 可以进行排序
disabled: false,
// 为拖拽时产生的副本添加一个class
ghostClass: "newclass",
// 为选中的元素添加一个class
chosenClass: "addclass",
// 禁用html5原有的样式
forceFallback: true,
// 排序发生变化时调用的函数
onUpdate: function (event) {
const newVal = props.modelValue;
const oldItem = newVal[event.oldIndex as number];
newVal[event.oldIndex as number] = newVal[event.newIndex as number];
newVal[event.newIndex as number] = oldItem;
//将数据传给父组件
emits("update:modelValue", newVal);
},
});
});
}
defineExpose({
boxStyle,
});
</script>
<style scoped>
#box {
display: flex;
/* width: 100%; */
/* height: 100%; */
overflow: scroll;
overflow-y: none;
}
</style>
父组件
```javascript
在这里插入代码片
<template>
<div class="container">
<TableComponent v-model="data.tabList" layout="x">
<template v-slot="scope">
<div class="items">{
{ scope.msg.name }}</div>
</template>
</TableComponent>
</div>
</template>
<script setup lang="ts">
import TableComponent from "@/components/TabComponent.vue";
import { reactive, watch } from "vue";
interface ITabItem {
id: string;
index: number;
name: string;
}
interface IData {
tabList: ITabItem[];
}
const data = reactive<IData>({
tabList: [
{
id: "ie",
index: 4,
name: "e",
},
{
id: "id",
index: 3,
name: "d",
},
{
id: "ic",
index: 2,
name: "c",
},
{
id: "ib",
index: 1,
name: "b",
},
{
id: "ia",
index: 0,
name: "a",
},
],
});
watch(
() => data.tabList,
(val) => {
console.log("更新了", val);
},
{
deep: true,
}
);
defineExpose({
data,
});
</script>
<style scoped>
.container {
width: 300px;
height: 300px;
background-color: green;
}
.items {
width: 100px;
height: 100px;
background-color: red;
border: 1px solid black;
}
</style>
注意点:引入第三方库的时候需要自定义生命类型 可以安装类型声明文件, npm i @types/第三方库包名 --save-dev
边栏推荐
猜你喜欢

STC8H Development (15): GPIO Drives Ci24R1 Wireless Module

In-depth analysis of Apache EventMesh cloud-native distributed event-driven architecture

leetcode 刷题日记 计算右侧小于当前元素的个数

Js fifteen interview questions (with answers)

Flask introductory learning tutorial

The kvm virtual machine cannot be started, NOT available, and the PV is larger than the partition

Converting angles to radians

一文让你快速了解隐式类型转换【整型提升】!

任务流执行器是如何工作的?

【微服务~Nacos】Nacos之配置中心
随机推荐
Bean life cycle
Quotefancy ,提供鼓舞人心语录的壁纸网站 - 倾城之链
简单问题窥见数学
js数组对象去重
xctf攻防世界 Web高手进阶区 ics-05
js array object deduplication
【GORM】模型关系-HasMany关系
SQLi-LABS Page-2 (Adv Injections)
Usage of placeholder function in Tensorflow
Arcgis工具箱无法使用,显示“XML包含错误“的解决方法
[Cloud Native] 4.2 DevOps Lectures
从源码方面来分析Fragment管理中 Add() 方法
跨端技术方案选什么好?
【stack】【queue】【priority_queue】【deque】Detailed explanation
Converting angles to radians
Cookie, session, token
README_Albumentations
级联下拉菜单的实现「建议收藏」
The kvm virtual machine cannot be started, NOT available, and the PV is larger than the partition
小程序+自定义插件的关键性