mirror of
https://gitee.com/log4j/pig-ui.git
synced 2024-12-31 09:12:10 +08:00
'admin-21.06.24:新增拖动指令及其演示界面、优化登录页,锁屏界面'
This commit is contained in:
parent
54bbaa1946
commit
0c2026d37e
@ -2,6 +2,15 @@
|
|||||||
|
|
||||||
🎉🎉🔥 `vue-next-admin` 基于 vue3.x 、Typescript、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
|
🎉🎉🔥 `vue-next-admin` 基于 vue3.x 、Typescript、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
|
||||||
|
|
||||||
|
## 1.0.7
|
||||||
|
|
||||||
|
`2021.06.24`
|
||||||
|
|
||||||
|
- 🌟 更新 依赖更新最新版本
|
||||||
|
- 🎉 新增 拖动指令及其演示界面
|
||||||
|
- 🎯 优化 锁屏界面,解锁提示
|
||||||
|
- 🎯 优化 登录页在手机上显示的效果
|
||||||
|
|
||||||
## 1.0.6
|
## 1.0.6
|
||||||
|
|
||||||
`2021.06.23`
|
`2021.06.23`
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-next-admin",
|
"name": "vue-next-admin",
|
||||||
"version": "1.0.6",
|
"version": "1.0.7",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
@ -13,8 +13,8 @@
|
|||||||
"cropperjs": "^1.5.12",
|
"cropperjs": "^1.5.12",
|
||||||
"echarts": "^5.1.2",
|
"echarts": "^5.1.2",
|
||||||
"echarts-wordcloud": "^2.0.0",
|
"echarts-wordcloud": "^2.0.0",
|
||||||
"element-plus": "^1.0.2-beta.48",
|
"element-plus": "^1.0.2-beta.51",
|
||||||
"mitt": "^2.1.0",
|
"mitt": "^3.0.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"print-js": "^1.6.0",
|
"print-js": "^1.6.0",
|
||||||
"qrcodejs2-fixes": "^0.0.2",
|
"qrcodejs2-fixes": "^0.0.2",
|
||||||
|
@ -48,6 +48,7 @@ export default {
|
|||||||
pagesPreview: 'Large preview',
|
pagesPreview: 'Large preview',
|
||||||
pagesWaves: 'Wave effect',
|
pagesWaves: 'Wave effect',
|
||||||
pagesTree: 'tree alter table',
|
pagesTree: 'tree alter table',
|
||||||
|
pagesDrag: 'Drag command',
|
||||||
chartIndex: 'chartIndex',
|
chartIndex: 'chartIndex',
|
||||||
personal: 'personal',
|
personal: 'personal',
|
||||||
tools: 'tools',
|
tools: 'tools',
|
||||||
|
@ -48,6 +48,7 @@ export default {
|
|||||||
pagesPreview: '大图预览',
|
pagesPreview: '大图预览',
|
||||||
pagesWaves: '波浪效果',
|
pagesWaves: '波浪效果',
|
||||||
pagesTree: '树形改表格',
|
pagesTree: '树形改表格',
|
||||||
|
pagesDrag: '拖动指令',
|
||||||
chartIndex: '大数据图表',
|
chartIndex: '大数据图表',
|
||||||
personal: '个人中心',
|
personal: '个人中心',
|
||||||
tools: '工具类集合',
|
tools: '工具类集合',
|
||||||
|
@ -48,6 +48,7 @@ export default {
|
|||||||
pagesPreview: '大圖預覽',
|
pagesPreview: '大圖預覽',
|
||||||
pagesWaves: '波浪效果',
|
pagesWaves: '波浪效果',
|
||||||
pagesTree: '樹形改表格',
|
pagesTree: '樹形改表格',
|
||||||
|
pagesDrag: '拖動指令',
|
||||||
chartIndex: '大資料圖表',
|
chartIndex: '大資料圖表',
|
||||||
personal: '個人中心',
|
personal: '個人中心',
|
||||||
tools: '工具類集合',
|
tools: '工具類集合',
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="layout-lock-screen-date-box-info">{{ time.mdq }}</div>
|
<div class="layout-lock-screen-date-box-info">{{ time.mdq }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="layout-lock-screen-date-top">
|
||||||
|
<i class="el-icon-top"></i>
|
||||||
|
<div class="layout-lock-screen-date-top-text">上滑解锁</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<transition name="el-zoom-in-center">
|
<transition name="el-zoom-in-center">
|
||||||
<div v-show="isShowLoockLogin" class="layout-lock-screen-login">
|
<div v-show="isShowLoockLogin" class="layout-lock-screen-login">
|
||||||
@ -52,11 +56,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { nextTick, onMounted, reactive, toRefs, ref, onUnmounted, getCurrentInstance } from 'vue';
|
import { nextTick, onMounted, reactive, toRefs, ref, onUnmounted, getCurrentInstance, defineComponent } from 'vue';
|
||||||
import { useStore } from '/@/store/index';
|
import { useStore } from '/@/store/index';
|
||||||
import { formatDate } from '/@/utils/formatTime';
|
import { formatDate } from '/@/utils/formatTime';
|
||||||
import { Local } from '/@/utils/storage';
|
import { Local } from '/@/utils/storage';
|
||||||
export default {
|
export default defineComponent({
|
||||||
name: 'layoutLockScreen',
|
name: 'layoutLockScreen',
|
||||||
setup() {
|
setup() {
|
||||||
const { proxy } = getCurrentInstance() as any;
|
const { proxy } = getCurrentInstance() as any;
|
||||||
@ -182,7 +186,7 @@ export default {
|
|||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@ -204,7 +208,7 @@ export default {
|
|||||||
}
|
}
|
||||||
.layout-lock-screen-img {
|
.layout-lock-screen-img {
|
||||||
@extend .layout-lock-screen-fixed;
|
@extend .layout-lock-screen-fixed;
|
||||||
background-image: url('https://img6.bdstatic.com/img/image/pcindex/sunjunpchuazhoutu.JPG');
|
background-image: url('https://gitee.com/lyt-top/vue-next-admin-images/raw/master/images/03.jpg');
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
z-index: 9999991;
|
z-index: 9999991;
|
||||||
}
|
}
|
||||||
@ -234,6 +238,53 @@ export default {
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&-top {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
border-radius: 100%;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
color: #ffffff;
|
||||||
|
opacity: 0.8;
|
||||||
|
position: absolute;
|
||||||
|
right: 30px;
|
||||||
|
bottom: 50px;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
i {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
&-text {
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 150%;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #ffffff;
|
||||||
|
left: 50%;
|
||||||
|
line-height: 1.2;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
width: 35px;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.5);
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
color: #ffffff;
|
||||||
|
opacity: 1;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
i {
|
||||||
|
transform: translateY(-40px);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
.layout-lock-screen-date-top-text {
|
||||||
|
opacity: 1;
|
||||||
|
top: 50%;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&-login {
|
&-login {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -755,6 +755,21 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
|
|||||||
icon: 'iconfont icon-shuxingtu',
|
icon: 'iconfont icon-shuxingtu',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/pages/drag',
|
||||||
|
name: 'pagesDrag',
|
||||||
|
component: () => import('/@/views/pages/drag/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'message.router.pagesDrag',
|
||||||
|
isLink: '',
|
||||||
|
isHide: false,
|
||||||
|
isKeepAlive: true,
|
||||||
|
isAffix: false,
|
||||||
|
isIframe: false,
|
||||||
|
auth: ['admin', 'test'],
|
||||||
|
icon: 'el-icon-thumb',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
padding: 20px 0 !important;
|
padding: 20px 0 !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
box-shadow: unset !important;
|
box-shadow: unset !important;
|
||||||
|
border: none !important;
|
||||||
}
|
}
|
||||||
.login-copyright {
|
.login-copyright {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
|
@ -52,3 +52,158 @@ export function wavesDirective(app: App) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义拖动指令
|
||||||
|
* @description 使用方式:v-drag="[dragDom,dragHeader]",如 `<div v-drag="['.drag-container .el-dialog', '.drag-container .el-dialog__header']"></div>`
|
||||||
|
* @description dragDom 要拖动的元素,dragHeader 要拖动的 Header 位置
|
||||||
|
* @link 注意:https://github.com/element-plus/element-plus/issues/522
|
||||||
|
* @lick 参考:https://blog.csdn.net/weixin_46391323/article/details/105228020?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-10&spm=1001.2101.3001.4242
|
||||||
|
*/
|
||||||
|
export function dragDirective(app: App) {
|
||||||
|
app.directive('drag', {
|
||||||
|
mounted(el, binding) {
|
||||||
|
if (!binding.value) return false;
|
||||||
|
const dragDom = document.querySelector(binding.value[0]) as HTMLElement;
|
||||||
|
const dragHeader = document.querySelector(binding.value[1]) as HTMLElement;
|
||||||
|
|
||||||
|
dragHeader.onmouseover = () => (dragHeader.style.cursor = `move`);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pc端,哪个大佬优化下,谢谢!
|
||||||
|
* onmousedown 鼠标按下触发事件
|
||||||
|
* onmousemove 鼠标按下时持续触发事件
|
||||||
|
* onmouseup 鼠标抬起触发事件
|
||||||
|
*/
|
||||||
|
dragHeader.onmousedown = (e) => {
|
||||||
|
// 鼠标按下,计算当前元素距离可视区的距离
|
||||||
|
const disX = e.clientX - dragHeader.offsetLeft;
|
||||||
|
const disY = e.clientY - dragHeader.offsetTop;
|
||||||
|
|
||||||
|
// body当前宽度
|
||||||
|
const screenWidth = document.body.clientWidth;
|
||||||
|
// 可见区域高度(应为body高度,可某些环境下无法获取)
|
||||||
|
const screenHeight = document.documentElement.clientHeight;
|
||||||
|
|
||||||
|
// 对话框宽度
|
||||||
|
const dragDomWidth = dragDom.offsetWidth;
|
||||||
|
// 对话框高度
|
||||||
|
const dragDomheight = dragDom.offsetHeight;
|
||||||
|
|
||||||
|
const minDragDomLeft = dragDom.offsetLeft;
|
||||||
|
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
|
||||||
|
|
||||||
|
const minDragDomTop = dragDom.offsetTop;
|
||||||
|
const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
|
||||||
|
|
||||||
|
// 获取到的值带px 正则匹配替换
|
||||||
|
let styL: any = getComputedStyle(dragDom).left;
|
||||||
|
let styT: any = getComputedStyle(dragDom).top;
|
||||||
|
|
||||||
|
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
|
||||||
|
if (styL.includes('%')) {
|
||||||
|
styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100);
|
||||||
|
styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100);
|
||||||
|
} else {
|
||||||
|
styL = +styL.replace(/\px/g, '');
|
||||||
|
styT = +styT.replace(/\px/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.onmousemove = (e) => {
|
||||||
|
// 通过事件委托,计算移动的距离
|
||||||
|
let left = e.clientX - disX;
|
||||||
|
let top = e.clientY - disY;
|
||||||
|
|
||||||
|
// 边界处理
|
||||||
|
if (-left > minDragDomLeft) {
|
||||||
|
left = -minDragDomLeft;
|
||||||
|
} else if (left > maxDragDomLeft) {
|
||||||
|
left = maxDragDomLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-top > minDragDomTop) {
|
||||||
|
top = -minDragDomTop;
|
||||||
|
} else if (top > maxDragDomTop) {
|
||||||
|
top = maxDragDomTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移动当前元素
|
||||||
|
dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
|
||||||
|
};
|
||||||
|
|
||||||
|
document.onmouseup = () => {
|
||||||
|
document.onmousemove = null;
|
||||||
|
document.onmouseup = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动端,哪个大佬优化下,谢谢!
|
||||||
|
* ontouchstart 当按下手指时,触发ontouchstart
|
||||||
|
* ontouchmove 当移动手指时,触发ontouchmove
|
||||||
|
* ontouchend 当移走手指时,触发ontouchend
|
||||||
|
*/
|
||||||
|
dragHeader.ontouchstart = (e) => {
|
||||||
|
// 鼠标按下,计算当前元素距离可视区的距离
|
||||||
|
const disX = e.touches[0].clientX - dragHeader.offsetLeft;
|
||||||
|
const disY = e.touches[0].clientY - dragHeader.offsetTop;
|
||||||
|
|
||||||
|
// body当前宽度
|
||||||
|
const screenWidth = document.body.clientWidth;
|
||||||
|
// 可见区域高度(应为body高度,可某些环境下无法获取)
|
||||||
|
const screenHeight = document.documentElement.clientHeight;
|
||||||
|
|
||||||
|
// 对话框宽度
|
||||||
|
const dragDomWidth = dragDom.offsetWidth;
|
||||||
|
// 对话框高度
|
||||||
|
const dragDomheight = dragDom.offsetHeight;
|
||||||
|
|
||||||
|
const minDragDomLeft = dragDom.offsetLeft;
|
||||||
|
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
|
||||||
|
|
||||||
|
const minDragDomTop = dragDom.offsetTop;
|
||||||
|
const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
|
||||||
|
|
||||||
|
// 获取到的值带px 正则匹配替换
|
||||||
|
let styL: any = getComputedStyle(dragDom).left;
|
||||||
|
let styT: any = getComputedStyle(dragDom).top;
|
||||||
|
|
||||||
|
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
|
||||||
|
if (styL.includes('%')) {
|
||||||
|
styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100);
|
||||||
|
styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100);
|
||||||
|
} else {
|
||||||
|
styL = +styL.replace(/\px/g, '');
|
||||||
|
styT = +styT.replace(/\px/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
document.ontouchmove = (e) => {
|
||||||
|
// 通过事件委托,计算移动的距离
|
||||||
|
let left = e.touches[0].clientX - disX;
|
||||||
|
let top = e.touches[0].clientY - disY;
|
||||||
|
|
||||||
|
// 边界处理
|
||||||
|
if (-left > minDragDomLeft) {
|
||||||
|
left = -minDragDomLeft;
|
||||||
|
} else if (left > maxDragDomLeft) {
|
||||||
|
left = maxDragDomLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-top > minDragDomTop) {
|
||||||
|
top = -minDragDomTop;
|
||||||
|
} else if (top > maxDragDomTop) {
|
||||||
|
top = maxDragDomTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移动当前元素
|
||||||
|
dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
|
||||||
|
};
|
||||||
|
|
||||||
|
document.ontouchend = () => {
|
||||||
|
document.ontouchmove = null;
|
||||||
|
document.ontouchend = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
import { authDirective } from '/@/utils/authDirective';
|
import { authDirective } from '/@/utils/authDirective';
|
||||||
import { wavesDirective } from '/@/utils/customDirective';
|
import { wavesDirective, dragDirective } from '/@/utils/customDirective';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出指令方法:v-xxx
|
* 导出指令方法:v-xxx
|
||||||
* @methods authDirective 用户权限指令,用法:v-auth
|
* @methods authDirective 用户权限指令,用法:v-auth
|
||||||
* @methods wavesDirective 按钮波浪指令,用法:v-waves
|
* @methods wavesDirective 按钮波浪指令,用法:v-waves
|
||||||
|
* @methods dragDirective 自定义拖动指令,用法:v-drag
|
||||||
*/
|
*/
|
||||||
export function directive(app: App) {
|
export function directive(app: App) {
|
||||||
// 用户权限指令
|
// 用户权限指令
|
||||||
authDirective(app);
|
authDirective(app);
|
||||||
// 按钮波浪指令
|
// 按钮波浪指令
|
||||||
wavesDirective(app);
|
wavesDirective(app);
|
||||||
|
// 自定义拖动指令
|
||||||
|
dragDirective(app);
|
||||||
}
|
}
|
||||||
|
57
src/views/pages/drag/index.vue
Normal file
57
src/views/pages/drag/index.vue
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<template>
|
||||||
|
<div class="drag-container">
|
||||||
|
<el-card shadow="hover" header="拖动指令效果(v-drag)作用于 Dialog 对话框">
|
||||||
|
<el-button type="primary" @click="dialogVisible = true" size="small" icon="el-icon-thumb">点击打开 Dialog</el-button>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-card shadow="hover" header="自定义div" class="mt15">
|
||||||
|
<div class="drag-dom">
|
||||||
|
<div class="drag-header">
|
||||||
|
<el-button type="success" size="small" icon="el-icon-thumb" v-drag="['.drag-container .drag-dom', '.drag-container .drag-header']"
|
||||||
|
>按住进行拖动测试</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-dialog v-model="dialogVisible" width="769px">
|
||||||
|
<template #title>
|
||||||
|
<div v-drag="['.drag-container .el-dialog', '.drag-container .el-dialog__header']">拖动指令效果(v-drag)</div>
|
||||||
|
</template>
|
||||||
|
<p>鼠标放标题头进行 Dialog 对话框拖动</p>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false" size="small">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="dialogVisible = false" size="small">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { toRefs, reactive, defineComponent } from 'vue';
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'pagesDrag',
|
||||||
|
setup() {
|
||||||
|
const state = reactive({
|
||||||
|
dialogVisible: false,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
...toRefs(state),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.drag-container {
|
||||||
|
.drag-dom {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
.drag-header {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user