Trong các dự án, cửa sổ đối thoại của Element thường được sử dụng nhiều. Tuy nhiên, nếu có quá nhiều lớp chồng lên nhau sẽ gây khó chịu cho người dùng. Sử dụng cửa sổ đối thoại dạng kéo thả sẽ cải thiện trải nghiệm người dùng.
Sử dụng thư viện vuedraggable dựa trên Sortable.js để thực hiện chức năng kéo thả.
Cài đặt
npm install vuedraggable --save
Tạo một tệp JavaScript mới trong thành phần chung và kết hợp với chỉ thị tùy chỉnh của Vue để đạt được hiệu ứng kéo thả.
import Vue from 'vue';
Vue.directive('draggableDialog', {
bind(el, binding, vnode) {
const headerEl = el.querySelector('.el-dialog__header');
const dialogEl = el.querySelector('.el-dialog');
headerEl.style.cssText += ';cursor:move;';
dialogEl.style.cssText += ';top:0px;';
const getStyle = (() => {
if (window.document.currentStyle) {
return (element, attr) => element.currentStyle[attr];
} else {
return (element, attr) => window.getComputedStyle(element)[attr];
}
})();
headerEl.onmousedown = (e) => {
const startX = e.clientX - headerEl.offsetLeft;
const startY = e.clientY - headerEl.offsetTop;
const screenWidth = document.body.clientWidth;
const screenHeight = document.documentElement.clientHeight;
const dialogWidth = dialogEl.offsetWidth;
const dialogHeight = dialogEl.offsetHeight;
const minLeft = dialogEl.offsetLeft;
const maxLeft = screenWidth - dialogEl.offsetLeft - dialogWidth;
const minTop = dialogEl.offsetTop;
const maxTop = screenHeight - dialogEl.offsetTop - dialogHeight;
let leftVal = getStyle(dialogEl, 'left');
let topVal = getStyle(dialogEl, 'top');
if (leftVal.includes('%')) {
leftVal = +document.body.clientWidth * (+leftVal.replace(/\%/g, '') / 100);
topVal = +document.body.clientHeight * (+topVal.replace(/\%/g, '') / 100);
} else {
leftVal = +leftVal.replace(/px/g, '');
topVal = +topVal.replace(/px/g, '');
}
document.onmousemove = function (event) {
let currentX = event.clientX - startX;
let currentY = event.clientY - startY;
if (currentX < -minLeft) {
currentX = -minLeft;
} else if (currentX > maxLeft) {
currentX = maxLeft;
}
if (currentY < -minTop) {
currentY = -minTop;
} else if (currentY > maxTop) {
currentY = maxTop;
}
dialogEl.style.cssText += `;left:${currentX + leftVal}px;top:${currentY + topVal}px;`;
};
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
};
}
}
});
Sử dụng thuộc tính v-draggableDialog trong trang để đạt được hiệu ứng mong muốn.
<el-dialog
v-draggableDialog
:title="dialogTitle"
:visible.sync="showDialog"
:before-close="closeHandler"
:close-on-click-modal="false"
width="50%">
<div class="content-area">
<div class="department-tree">
<div class="dept-title">Quản lý phòng ban</div>
<el-tree
:data="treeInfo"
lazy
:load="loadDeptNode"
accordion
:props="defaultProps"
:default-expand-all="false">
</el-tree>
</div>
<div class="user-info">
<el-form inline>
<el-form-item label="Mã người dùng">
<el-input v-model="searchUser.userId" size="mini"></el-input>
</el-form-item>
<el-form-item label="Tên người dùng">
<el-input v-model="searchUser.userName" size="mini"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="queryUsers" size="mini">Tìm kiếm</el-button>
</el-form-item>
<el-form-item>
<el-button type="success" @click="addNewUser" size="mini">Thêm người dùng</el-button>
</el-form-item>
</el-form>
<el-table
:data="tableInfo"
class="userTable"
style="width:100%;">
<el-table-column type="selection" width="50"></el-table-column>
<el-table-column prop="id" width="60" label="ID đăng nhập"></el-table-column>
<el-table-column prop="userName" label="Tên người dùng"></el-table-column>
<el-table-column prop="deptName" label="Phòng ban"></el-table-column>
<el-table-column prop="phone" label="Số điện thoại"></el-table-column>
</el-table>
</div>
</div>
</el-dialog>