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 分支)
|
||||
|
||||
## 1.0.7
|
||||
|
||||
`2021.06.24`
|
||||
|
||||
- 🌟 更新 依赖更新最新版本
|
||||
- 🎉 新增 拖动指令及其演示界面
|
||||
- 🎯 优化 锁屏界面,解锁提示
|
||||
- 🎯 优化 登录页在手机上显示的效果
|
||||
|
||||
## 1.0.6
|
||||
|
||||
`2021.06.23`
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vue-next-admin",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.7",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
@ -13,8 +13,8 @@
|
||||
"cropperjs": "^1.5.12",
|
||||
"echarts": "^5.1.2",
|
||||
"echarts-wordcloud": "^2.0.0",
|
||||
"element-plus": "^1.0.2-beta.48",
|
||||
"mitt": "^2.1.0",
|
||||
"element-plus": "^1.0.2-beta.51",
|
||||
"mitt": "^3.0.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"print-js": "^1.6.0",
|
||||
"qrcodejs2-fixes": "^0.0.2",
|
||||
|
@ -48,6 +48,7 @@ export default {
|
||||
pagesPreview: 'Large preview',
|
||||
pagesWaves: 'Wave effect',
|
||||
pagesTree: 'tree alter table',
|
||||
pagesDrag: 'Drag command',
|
||||
chartIndex: 'chartIndex',
|
||||
personal: 'personal',
|
||||
tools: 'tools',
|
||||
|
@ -48,6 +48,7 @@ export default {
|
||||
pagesPreview: '大图预览',
|
||||
pagesWaves: '波浪效果',
|
||||
pagesTree: '树形改表格',
|
||||
pagesDrag: '拖动指令',
|
||||
chartIndex: '大数据图表',
|
||||
personal: '个人中心',
|
||||
tools: '工具类集合',
|
||||
|
@ -48,6 +48,7 @@ export default {
|
||||
pagesPreview: '大圖預覽',
|
||||
pagesWaves: '波浪效果',
|
||||
pagesTree: '樹形改表格',
|
||||
pagesDrag: '拖動指令',
|
||||
chartIndex: '大資料圖表',
|
||||
personal: '個人中心',
|
||||
tools: '工具類集合',
|
||||
|
@ -19,6 +19,10 @@
|
||||
</div>
|
||||
<div class="layout-lock-screen-date-box-info">{{ time.mdq }}</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>
|
||||
<transition name="el-zoom-in-center">
|
||||
<div v-show="isShowLoockLogin" class="layout-lock-screen-login">
|
||||
@ -52,11 +56,11 @@
|
||||
</template>
|
||||
|
||||
<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 { formatDate } from '/@/utils/formatTime';
|
||||
import { Local } from '/@/utils/storage';
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'layoutLockScreen',
|
||||
setup() {
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
@ -182,7 +186,7 @@ export default {
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@ -204,7 +208,7 @@ export default {
|
||||
}
|
||||
.layout-lock-screen-img {
|
||||
@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%;
|
||||
z-index: 9999991;
|
||||
}
|
||||
@ -234,6 +238,53 @@ export default {
|
||||
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 {
|
||||
position: relative;
|
||||
|
@ -755,6 +755,21 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
|
||||
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;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: unset !important;
|
||||
border: none !important;
|
||||
}
|
||||
.login-copyright {
|
||||
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 { authDirective } from '/@/utils/authDirective';
|
||||
import { wavesDirective } from '/@/utils/customDirective';
|
||||
import { wavesDirective, dragDirective } from '/@/utils/customDirective';
|
||||
|
||||
/**
|
||||
* 导出指令方法:v-xxx
|
||||
* @methods authDirective 用户权限指令,用法:v-auth
|
||||
* @methods wavesDirective 按钮波浪指令,用法:v-waves
|
||||
* @methods dragDirective 自定义拖动指令,用法:v-drag
|
||||
*/
|
||||
export function directive(app: App) {
|
||||
// 用户权限指令
|
||||
authDirective(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