init
This commit is contained in:
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -0,0 +1,311 @@
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "LayTransfer",
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import "./index.less";
|
||||
import LayInput from "../input/index.vue";
|
||||
import LayButton from "../button/index.vue";
|
||||
import LayCheckbox from "../checkbox/index.vue";
|
||||
import { computed, Ref, ref, useSlots, watch } from "vue";
|
||||
import { BooleanOrString, Recordable } from "../../types";
|
||||
|
||||
export interface TransferProps {
|
||||
id?: string;
|
||||
title?: string[];
|
||||
width?: string;
|
||||
height?: string;
|
||||
showSearch?: BooleanOrString;
|
||||
dataSource: Recordable[];
|
||||
modelValue?: Recordable[];
|
||||
}
|
||||
|
||||
const slots = useSlots();
|
||||
|
||||
const props = withDefaults(defineProps<TransferProps>(), {
|
||||
id: "id",
|
||||
title: () => ["主列表", "副列表"],
|
||||
dataSource: () => [],
|
||||
showSearch: false,
|
||||
modelValue: () => [],
|
||||
width: "200px",
|
||||
height: "360px",
|
||||
});
|
||||
|
||||
const emits = defineEmits(["update:modelValue", "change"]);
|
||||
|
||||
const leftDataSource: Ref<any[]> = ref([]);
|
||||
const rightDataSource: Ref<any[]> = ref([]);
|
||||
const _leftDataSource: Ref<any[]> = ref([]);
|
||||
const _rightDataSource: Ref<any[]> = ref([]);
|
||||
const leftSelectedKeys: Ref<string[]> = ref([]);
|
||||
const rightSelectedKeys: Ref<string[]> = ref([]);
|
||||
const allLeftChecked = ref(false);
|
||||
const allRightChecked = ref(false);
|
||||
const hasLeftChecked = ref(false);
|
||||
const hasRightChecked = ref(false);
|
||||
|
||||
const allLeftChange = (isChecked: boolean) => {
|
||||
if (isChecked) {
|
||||
const datasources = leftDataSource.value.filter((item: any) => {
|
||||
return !item.disabled;
|
||||
});
|
||||
const ids = datasources.map((item) => {
|
||||
return item[props.id];
|
||||
});
|
||||
leftSelectedKeys.value = [...ids];
|
||||
} else {
|
||||
leftSelectedKeys.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => [props.modelValue, props.dataSource],
|
||||
() => {
|
||||
let targetDataSource: any[] = [];
|
||||
|
||||
props.dataSource.forEach((ds) => {
|
||||
if (props.modelValue.includes(ds[props.id])) {
|
||||
targetDataSource.push(ds);
|
||||
}
|
||||
});
|
||||
|
||||
leftDataSource.value = props.dataSource.filter(
|
||||
(item) => !props.modelValue.includes(item[props.id])
|
||||
);
|
||||
|
||||
_leftDataSource.value = props.dataSource.filter(
|
||||
(item) => !props.modelValue.includes(item[props.id])
|
||||
);
|
||||
|
||||
rightDataSource.value = [...targetDataSource];
|
||||
_rightDataSource.value = [...targetDataSource];
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
leftSelectedKeys,
|
||||
() => {
|
||||
if (
|
||||
leftDataSource.value.length === leftSelectedKeys.value.length &&
|
||||
leftDataSource.value.length != 0
|
||||
) {
|
||||
allLeftChecked.value = true;
|
||||
} else {
|
||||
allLeftChecked.value = false;
|
||||
}
|
||||
if (leftSelectedKeys.value.length > 0 && leftDataSource.value.length != 0) {
|
||||
hasLeftChecked.value = true;
|
||||
} else {
|
||||
hasLeftChecked.value = false;
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const allRightChange = (checked: any) => {
|
||||
if (checked) {
|
||||
const datasources = rightDataSource.value.filter((item: any) => {
|
||||
return !item.disabled;
|
||||
});
|
||||
const ids = datasources.map((item) => {
|
||||
return item[props.id];
|
||||
});
|
||||
rightSelectedKeys.value = [...ids];
|
||||
} else {
|
||||
rightSelectedKeys.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
rightSelectedKeys,
|
||||
() => {
|
||||
if (
|
||||
rightDataSource.value.length === rightSelectedKeys.value.length &&
|
||||
rightDataSource.value.length > 0
|
||||
) {
|
||||
allRightChecked.value = true;
|
||||
} else {
|
||||
allRightChecked.value = false;
|
||||
}
|
||||
if (
|
||||
rightSelectedKeys.value.length > 0 &&
|
||||
rightDataSource.value.length != 0
|
||||
) {
|
||||
hasRightChecked.value = true;
|
||||
} else {
|
||||
hasRightChecked.value = false;
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const add = () => {
|
||||
if (leftSelectedKeys.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let targetKeys: any[] = [];
|
||||
|
||||
leftDataSource.value.forEach((item) => {
|
||||
if (leftSelectedKeys.value.indexOf(item[props.id]) != -1) {
|
||||
targetKeys.push(item[props.id]);
|
||||
}
|
||||
});
|
||||
|
||||
rightDataSource.value.forEach((item) => {
|
||||
targetKeys.push(item[props.id]);
|
||||
});
|
||||
|
||||
emits("change", targetKeys);
|
||||
emits("update:modelValue", targetKeys);
|
||||
|
||||
leftSelectedKeys.value = [];
|
||||
};
|
||||
|
||||
const remove = () => {
|
||||
if (rightSelectedKeys.value.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let targetKeys: any[] = [];
|
||||
|
||||
rightDataSource.value.forEach((item) => {
|
||||
if (rightSelectedKeys.value.indexOf(item[props.id]) == -1) {
|
||||
targetKeys.push(item[props.id]);
|
||||
}
|
||||
});
|
||||
|
||||
emits("change", targetKeys);
|
||||
emits("update:modelValue", targetKeys);
|
||||
|
||||
rightSelectedKeys.value = [];
|
||||
};
|
||||
|
||||
const searchLeft = (e: any) => {
|
||||
if (e === "") {
|
||||
leftDataSource.value = _leftDataSource.value;
|
||||
}
|
||||
leftDataSource.value = _leftDataSource.value.filter((item) => {
|
||||
if (item.title.indexOf(e) != -1) {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const searchRight = (e: any) => {
|
||||
if (e === "") {
|
||||
rightDataSource.value = _rightDataSource.value;
|
||||
}
|
||||
rightDataSource.value = _rightDataSource.value.filter((item) => {
|
||||
if (item.title.indexOf(e) != -1) {
|
||||
return item;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const boxStyle = computed(() => {
|
||||
return {
|
||||
width: props.width,
|
||||
height: props.height,
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="layui-transfer layui-form layui-border-box">
|
||||
<div class="layui-transfer-box" :style="boxStyle">
|
||||
<div class="layui-transfer-header">
|
||||
<LayCheckbox
|
||||
v-model="hasLeftChecked"
|
||||
:is-indeterminate="!allLeftChecked"
|
||||
skin="primary"
|
||||
value="all"
|
||||
@change="allLeftChange"
|
||||
>
|
||||
{{ title[0] }}
|
||||
</LayCheckbox>
|
||||
</div>
|
||||
<div class="layui-transfer-search" v-if="showSearch">
|
||||
<lay-input
|
||||
prefix-icon="layui-icon-search"
|
||||
@input="searchLeft"
|
||||
placeholder="关键词搜索"
|
||||
></lay-input>
|
||||
</div>
|
||||
<ul class="layui-transfer-data">
|
||||
<li v-for="dataSource in leftDataSource" :key="dataSource">
|
||||
<LayCheckbox
|
||||
v-model="leftSelectedKeys"
|
||||
skin="primary"
|
||||
:disabled="dataSource.disabled"
|
||||
:value="dataSource[id]"
|
||||
>
|
||||
<slot v-if="slots.item" name="item" :data="dataSource"></slot>
|
||||
<template v-else>{{ dataSource.title }}</template>
|
||||
</LayCheckbox>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="layui-transfer-footer" v-if="slots.leftFooter">
|
||||
<slot name="leftFooter"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-transfer-active">
|
||||
<div class="layui-transfer-button-group">
|
||||
<LayButton
|
||||
type="primary"
|
||||
:disabled="leftSelectedKeys.length == 0"
|
||||
@click="add"
|
||||
><i class="layui-icon layui-icon-next"></i
|
||||
></LayButton>
|
||||
<LayButton
|
||||
type="primary"
|
||||
:disabled="rightSelectedKeys.length == 0"
|
||||
@click="remove"
|
||||
><i class="layui-icon layui-icon-prev"></i
|
||||
></LayButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-transfer-box" :style="boxStyle">
|
||||
<div class="layui-transfer-header">
|
||||
<LayCheckbox
|
||||
v-model="hasRightChecked"
|
||||
:is-indeterminate="!allRightChecked"
|
||||
skin="primary"
|
||||
value="all"
|
||||
@change="allRightChange"
|
||||
>
|
||||
{{ title[1] }}
|
||||
</LayCheckbox>
|
||||
</div>
|
||||
<div class="layui-transfer-search" v-if="showSearch">
|
||||
<lay-input
|
||||
prefix-icon="layui-icon-search"
|
||||
@input="searchRight"
|
||||
placeholder="关键词搜索"
|
||||
></lay-input>
|
||||
</div>
|
||||
<ul class="layui-transfer-data">
|
||||
<li v-for="dataSource in rightDataSource" :key="dataSource">
|
||||
<LayCheckbox
|
||||
skin="primary"
|
||||
v-model="rightSelectedKeys"
|
||||
:disabled="dataSource.disabled"
|
||||
:value="dataSource[id]"
|
||||
>
|
||||
<slot v-if="slots.item" name="item" :data="dataSource"></slot>
|
||||
<template v-else>{{ dataSource.title }}</template>
|
||||
</LayCheckbox>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="layui-transfer-footer" v-if="slots.rightFooter">
|
||||
<slot name="rightFooter"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
xE<>A
|
||||
<EFBFBD>0E]<5D>C<>Jэ<4A>iV.<2E><10>&Ja<4A><61>d<EFBFBD><16><>NT<4E>o<EFBFBD>3<EFBFBD><33>(<0E><><EFBFBD>V<EFBFBD><56>yJ<0C><><EFBFBD>k.<2E>*<2A>H138<38>JOp<><07>g\N9&<17><><EFBFBD>C<EFBFBD>k<EFBFBD>:*<2A>}V)<29>~N<><4E><EFBFBD>0<EFBFBD><12><><EFBFBD><EFBFBD><EFBFBD>p<EFBFBD><70>fDvZu?<3F><>'<27> 1<>"[<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><15><><EFBFBD>:<3A>
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,170 @@
|
||||
module.exports = [
|
||||
{ name: "实心", class: "layui-icon-heart-fill" },
|
||||
{ name: "空心", class: "layui-icon-heart" },
|
||||
{ name: "亮度/晴", class: "layui-icon-light" },
|
||||
{ name: "时间/历史", class: "layui-icon-time" },
|
||||
{ name: "蓝牙", class: "layui-icon-bluetooth" },
|
||||
{ name: "@艾特", class: "layui-icon-at" },
|
||||
{ name: "静音", class: "layui-icon-mute" },
|
||||
{ name: "录音/麦克风", class: "layui-icon-mike" },
|
||||
{ name: "密钥/钥匙", class: "layui-icon-key" },
|
||||
{ name: "礼物/活动", class: "layui-icon-gift" },
|
||||
{ name: "邮箱", class: "layui-icon-email" },
|
||||
{ name: "RSS", class: "layui-icon-rss" },
|
||||
{ name: "WiFi", class: "layui-icon-wifi" },
|
||||
{ name: "退出/注销", class: "layui-icon-logout" },
|
||||
{ name: "Android 安卓", class: "layui-icon-android" },
|
||||
{ name: "Apple IOS 苹果", class: "layui-icon-ios" },
|
||||
{ name: "Windows", class: "layui-icon-windows" },
|
||||
{ name: "穿梭框", class: "layui-icon-transfer" },
|
||||
{ name: "客服", class: "layui-icon-service" },
|
||||
{ name: "减", class: "layui-icon-subtraction" },
|
||||
{ name: "加", class: "layui-icon-addition" },
|
||||
{ name: "滑块", class: "layui-icon-slider" },
|
||||
{ name: "打印", class: "layui-icon-print" },
|
||||
{ name: "导出", class: "layui-icon-export" },
|
||||
{ name: "列", class: "layui-icon-cols" },
|
||||
{ name: "退出全屏", class: "layui-icon-screen-restore" },
|
||||
{ name: "全屏", class: "layui-icon-screen-full" },
|
||||
{ name: "半星", class: "layui-icon-rate-half" },
|
||||
{ name: "星星-空心", class: "layui-icon-rate" },
|
||||
{ name: "星星-实心", class: "layui-icon-rate-solid" },
|
||||
{ name: "手机", class: "layui-icon-cellphone" },
|
||||
{ name: "验证码", class: "layui-icon-vercode" },
|
||||
{ name: "微信", class: "layui-icon-login-wechat" },
|
||||
{ name: "QQ", class: "layui-icon-login-qq" },
|
||||
{ name: "微博", class: "layui-icon-login-weibo" },
|
||||
{ name: "密码", class: "layui-icon-password" },
|
||||
{ name: "用户名", class: "layui-icon-username" },
|
||||
{ name: "刷新-粗", class: "layui-icon-refresh-three" },
|
||||
{ name: "授权", class: "layui-icon-auz" },
|
||||
{ name: "左向右伸缩菜单", class: "layui-icon-spread-left" },
|
||||
{ name: "右向左伸缩菜单", class: "layui-icon-shrink-right" },
|
||||
{ name: "雪花", class: "layui-icon-snowflake" },
|
||||
{ name: "提示说明", class: "layui-icon-tips" },
|
||||
{ name: "便签", class: "layui-icon-note" },
|
||||
{ name: "主页", class: "layui-icon-home" },
|
||||
{ name: "高级", class: "layui-icon-senior" },
|
||||
{ name: "刷新", class: "layui-icon-refresh" },
|
||||
{ name: "刷新", class: "layui-icon-refresh-one" },
|
||||
{ name: "旗帜", class: "layui-icon-flag" },
|
||||
{ name: "主题", class: "layui-icon-theme" },
|
||||
{ name: "消息-通知", class: "layui-icon-notice" },
|
||||
{ name: "网站", class: "layui-icon-website" },
|
||||
{ name: "控制台", class: "layui-icon-console" },
|
||||
{ name: "表情-惊讶", class: "layui-icon-face-surprised" },
|
||||
{ name: "设置-空心", class: "layui-icon-set" },
|
||||
{ name: "模板", class: "layui-icon-template-one" },
|
||||
{ name: "应用", class: "layui-icon-app" },
|
||||
{ name: "模板", class: "layui-icon-template" },
|
||||
{ name: "赞", class: "layui-icon-praise" },
|
||||
{ name: "踩", class: "layui-icon-tread" },
|
||||
{ name: "男", class: "layui-icon-male" },
|
||||
{ name: "女", class: "layui-icon-female" },
|
||||
{ name: "相机-空心", class: "layui-icon-camera" },
|
||||
{ name: "相机-实心", class: "layui-icon-camera-fill" },
|
||||
{ name: "菜单-水平", class: "layui-icon-more" },
|
||||
{ name: "菜单-垂直", class: "layui-icon-more-vertical" },
|
||||
{ name: "金额-人民币", class: "layui-icon-rmb" },
|
||||
{ name: "金额-美元", class: "layui-icon-dollar" },
|
||||
{ name: "钻石-等级", class: "layui-icon-diamond" },
|
||||
{ name: "火", class: "layui-icon-fire" },
|
||||
{ name: "返回", class: "layui-icon-return" },
|
||||
{ name: "位置-地图", class: "layui-icon-location" },
|
||||
{ name: "办公-阅读", class: "layui-icon-read" },
|
||||
{ name: "调查", class: "layui-icon-survey" },
|
||||
{ name: "表情-微笑", class: "layui-icon-face-smile" },
|
||||
{ name: "表情-哭泣", class: "layui-icon-face-cry" },
|
||||
{ name: "购物车", class: "layui-icon-cart-simple" },
|
||||
{ name: "购物车", class: "layui-icon-cart" },
|
||||
{ name: "下一页", class: "layui-icon-next" },
|
||||
{ name: "上一页", class: "layui-icon-prev" },
|
||||
{ name: "上传-空心-拖拽", class: "layui-icon-upload-drag" },
|
||||
{ name: "上传-实心", class: "layui-icon-upload" },
|
||||
{ name: "下载-圆圈", class: "layui-icon-download-circle" },
|
||||
{ name: "组件", class: "layui-icon-component" },
|
||||
{ name: "文件-粗", class: "layui-icon-file-b" },
|
||||
{ name: "用户", class: "layui-icon-user" },
|
||||
{ name: "发现-实心", class: "layui-icon-find-fill" },
|
||||
{ name: "loading", class: "layui-icon-loading" },
|
||||
{ name: "loading", class: "layui-icon-loading-one" },
|
||||
{ name: "添加", class: "layui-icon-add-one" },
|
||||
{ name: "播放", class: "layui-icon-play" },
|
||||
{ name: "暂停", class: "layui-icon-pause" },
|
||||
{ name: "音频-耳机", class: "layui-icon-headset" },
|
||||
{ name: "视频", class: "layui-icon-video" },
|
||||
{ name: "语音-声音", class: "layui-icon-voice" },
|
||||
{ name: "消息-通知-喇叭", class: "layui-icon-speaker" },
|
||||
{ name: "删除线", class: "layui-icon-fonts-del" },
|
||||
{ name: "代码", class: "layui-icon-fonts-code" },
|
||||
{ name: "HTML", class: "layui-icon-fonts-html" },
|
||||
{ name: "字体加粗", class: "layui-icon-fonts-strong" },
|
||||
{ name: "删除链接", class: "layui-icon-unlink" },
|
||||
{ name: "图片", class: "layui-icon-picture" },
|
||||
{ name: "链接", class: "layui-icon-link" },
|
||||
{ name: "表情-笑-粗", class: "layui-icon-face-smile-b" },
|
||||
{ name: "左对齐", class: "layui-icon-align-left" },
|
||||
{ name: "右对齐", class: "layui-icon-align-right" },
|
||||
{ name: "居中对齐", class: "layui-icon-align-center" },
|
||||
{ name: "字体-下划线", class: "layui-icon-fonts-u" },
|
||||
{ name: "字体-斜体", class: "layui-icon-fonts-i" },
|
||||
{ name: "Tabs 选项卡", class: "layui-icon-tabs" },
|
||||
{ name: "单选框-选中", class: "layui-icon-radio" },
|
||||
{ name: "单选框-候选", class: "layui-icon-circle" },
|
||||
{ name: "编辑", class: "layui-icon-edit" },
|
||||
{ name: "分享", class: "layui-icon-share" },
|
||||
{ name: "删除", class: "layui-icon-delete" },
|
||||
{ name: "表单", class: "layui-icon-form" },
|
||||
{ name: "手机-细体", class: "layui-icon-cellphone-fine" },
|
||||
{ name: "聊天 对话 沟通", class: "layui-icon-dialogue" },
|
||||
{ name: "文字格式化", class: "layui-icon-fonts-clear" },
|
||||
{ name: "窗口", class: "layui-icon-layer" },
|
||||
{ name: "日期", class: "layui-icon-date" },
|
||||
{ name: "水 下雨", class: "layui-icon-water" },
|
||||
{ name: "代码-圆圈", class: "layui-icon-code-circle" },
|
||||
{ name: "轮播组图", class: "layui-icon-carousel" },
|
||||
{ name: "翻页", class: "layui-icon-prev-circle" },
|
||||
{ name: "布局", class: "layui-icon-layouts" },
|
||||
{ name: "工具", class: "layui-icon-util" },
|
||||
{ name: "选择模板", class: "layui-icon-templeate-one" },
|
||||
{ name: "上传-圆圈", class: "layui-icon-upload-circle" },
|
||||
{ name: "树", class: "layui-icon-tree" },
|
||||
{ name: "表格", class: "layui-icon-table" },
|
||||
{ name: "图表", class: "layui-icon-chart" },
|
||||
{ name: "图标 报表 屏幕", class: "layui-icon-chart-screen" },
|
||||
{ name: "引擎", class: "layui-icon-engine" },
|
||||
{ name: "下三角", class: "layui-icon-triangle-d" },
|
||||
{ name: "右三角", class: "layui-icon-triangle-r" },
|
||||
{ name: "文件", class: "layui-icon-file" },
|
||||
{ name: "设置-小型", class: "layui-icon-set-sm" },
|
||||
{ name: "减少-圆圈", class: "layui-icon-reduce-circle" },
|
||||
{ name: "添加-圆圈", class: "layui-icon-add-circle" },
|
||||
{ name: "404", class: "layui-icon-not-found" },
|
||||
{ name: "关于", class: "layui-icon-about" },
|
||||
{ name: "箭头 向上", class: "layui-icon-up" },
|
||||
{ name: "箭头 向下", class: "layui-icon-down" },
|
||||
{ name: "箭头 向左", class: "layui-icon-left" },
|
||||
{ name: "箭头 向右", class: "layui-icon-right" },
|
||||
{ name: "圆点", class: "layui-icon-circle-dot" },
|
||||
{ name: "搜索", class: "layui-icon-search" },
|
||||
{ name: "设置-实心", class: "layui-icon-set-fill" },
|
||||
{ name: "群组", class: "layui-icon-group" },
|
||||
{ name: "好友", class: "layui-icon-friends" },
|
||||
{ name: "回复 评论 实心", class: "layui-icon-reply-fill" },
|
||||
{ name: "菜单 隐身 实心", class: "layui-icon-menu-fill" },
|
||||
{ name: "记录", class: "layui-icon-log" },
|
||||
{ name: "图片-细体", class: "layui-icon-picture-fine" },
|
||||
{ name: "表情-笑-细体", class: "layui-icon-face-smile-fine" },
|
||||
{ name: "列表", class: "layui-icon-list" },
|
||||
{ name: "发布 纸飞机", class: "layui-icon-release" },
|
||||
{ name: "对 OK", class: "layui-icon-ok" },
|
||||
{ name: "帮助", class: "layui-icon-help" },
|
||||
{ name: "客服", class: "layui-icon-chat" },
|
||||
{ name: "top 置顶", class: "layui-icon-top" },
|
||||
{ name: "收藏-空心", class: "layui-icon-star" },
|
||||
{ name: "收藏-实心", class: "layui-icon-star-fill" },
|
||||
{ name: "关闭-实心", class: "layui-icon-close-fill" },
|
||||
{ name: "关闭-空心", class: "layui-icon-close" },
|
||||
{ name: "正确", class: "layui-icon-ok-circle" },
|
||||
{ name: "添加-圆圈-细体", class: "layui-icon-add-circle-fine" },
|
||||
];
|
||||
Reference in New Issue
Block a user