Skip to content

Commit

Permalink
Merge pull request #150 from lin-xin/dev
Browse files Browse the repository at this point in the history
 修复使用index作为v-for的key
  • Loading branch information
lin-xin committed Dec 28, 2018
2 parents 81f571e + 9b30527 commit 718756b
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 7 deletions.
16 changes: 13 additions & 3 deletions src/components/common/Sidebar.vue
Expand Up @@ -94,12 +94,22 @@
},
{
icon: 'el-icon-rank',
index: 'drag',
title: '拖拽列表'
index: '6',
title: '拖拽组件',
subs: [
{
index: 'drag',
title: '拖拽列表',
},
{
index: 'dialog',
title: '拖拽弹框',
}
]
},
{
icon: 'el-icon-lx-warn',
index: '6',
index: '7',
title: '错误处理',
subs: [
{
Expand Down
80 changes: 80 additions & 0 deletions src/components/common/directives.js
@@ -0,0 +1,80 @@
import Vue from 'vue';

// v-dialogDrag: 弹窗拖拽属性
Vue.directive('dialogDrag', {
bind(el, binding, vnode, oldVnode) {
const dialogHeaderEl = el.querySelector('.el-dialog__header');
const dragDom = el.querySelector('.el-dialog');

dialogHeaderEl.style.cssText += ';cursor:move;'
dragDom.style.cssText += ';top:0px;'

// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
const sty = (() => {
if (window.document.currentStyle) {
return (dom, attr) => dom.currentStyle[attr];
} else {
return (dom, attr) => getComputedStyle(dom, false)[attr];
}
})()

dialogHeaderEl.onmousedown = (e) => {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - dialogHeaderEl.offsetLeft;
const disY = e.clientY - dialogHeaderEl.offsetTop;

const screenWidth = document.body.clientWidth; // body当前宽度
const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取)

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 = sty(dragDom, 'left');
let styT = sty(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 = function (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 = function (e) {
document.onmousemove = null;
document.onmouseup = null;
};
}
}
})
36 changes: 36 additions & 0 deletions src/components/page/DragDialog.vue
@@ -0,0 +1,36 @@
<template>
<section class="main">
<div class="crumbs">
<el-breadcrumb separator="/">
<el-breadcrumb-item><i class="el-icon-rank"></i> 拖拽组件</el-breadcrumb-item>
<el-breadcrumb-item>拖拽弹框</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="container">
<p>通过指令 v-dialogDrag 使 Dialog 对话框具有可拖拽的功能。</p>
<br>
<el-button type="primary" @click="visible = true;">点我弹框</el-button>
</div>
<el-dialog v-dialogDrag title="拖拽弹框" center :visible.sync="visible" width="30%">
我是一个可以拖拽的对话框!
<span slot="footer" class="dialog-footer">
<el-button @click="visible = false">取 消</el-button>
<el-button type="primary" @click="visible = false">确 定</el-button>
</span>
</el-dialog>
</section>
</template>

<script>
export default {
data(){
return {
visible: false
}
}
}
</script>

<style>
</style>
18 changes: 14 additions & 4 deletions src/components/page/DragList.vue
Expand Up @@ -2,7 +2,8 @@
<section class="main">
<div class="crumbs">
<el-breadcrumb separator="/">
<el-breadcrumb-item><i class="el-icon-rank"></i> 拖拽排序</el-breadcrumb-item>
<el-breadcrumb-item><i class="el-icon-rank"></i> 拖拽组件</el-breadcrumb-item>
<el-breadcrumb-item>拖拽排序</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="container">
Expand All @@ -15,7 +16,7 @@
<div class="item-title">todo</div>
<draggable v-model="todo" @remove="removeHandle" :options="dragOptions">
<transition-group tag="div" id="todo" class="item-ul">
<div v-for="(item,index) in todo" class="drag-list" :key="index">
<div v-for="item in todo" class="drag-list" :key="item.id">
{{item.content}}
</div>
</transition-group>
Expand All @@ -25,7 +26,7 @@
<div class="item-title">doing</div>
<draggable v-model="doing" @remove="removeHandle" :options="dragOptions">
<transition-group tag="div" id="doing" class="item-ul">
<div v-for="(item,index) in doing" class="drag-list" :key="index">
<div v-for="item in doing" class="drag-list" :key="item.id">
{{item.content}}
</div>
</transition-group>
Expand All @@ -35,7 +36,7 @@
<div class="item-title">done</div>
<draggable v-model="done" @remove="removeHandle" :options="dragOptions">
<transition-group tag="div" id="done" class="item-ul">
<div v-for="(item,index) in done" class="drag-list" :key="index">
<div v-for="item in done" class="drag-list" :key="item.id">
{{item.content}}
</div>
</transition-group>
Expand All @@ -60,34 +61,43 @@
},
todo: [
{
id: 1,
content: '开发图表组件'
},
{
id: 2,
content: '开发拖拽组件'
},
{
id: 3,
content: '开发权限测试组件'
}
],
doing: [
{
id: 1,
content: '开发登录注册页面'
},
{
id: 2,
content: '开发头部组件'
},
{
id: 3,
content: '开发表格相关组件'
},
{
id: 4,
content: '开发表单相关组件'
}
],
done:[
{
id: 1,
content: '初始化项目,生成工程目录,完成相关配置'
},
{
id: 2,
content: '开发项目整体框架'
}
]
Expand Down
1 change: 1 addition & 0 deletions src/main.js
Expand Up @@ -6,6 +6,7 @@ import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'; // 默认主题
// import '../static/css/theme-green/index.css'; // 浅绿色主题
import '../static/css/icon.css';
import './components/common/directives';
import "babel-polyfill";

Vue.use(ElementUI, { size: 'small' });
Expand Down
6 changes: 6 additions & 0 deletions src/router/index.js
Expand Up @@ -69,6 +69,12 @@ export default new Router({
component: resolve => require(['../components/page/DragList.vue'], resolve),
meta: { title: '拖拽列表' }
},
{
// 拖拽Dialog组件
path: '/dialog',
component: resolve => require(['../components/page/DragDialog.vue'], resolve),
meta: { title: '拖拽弹框' }
},
{
// 权限页面
path: '/permission',
Expand Down

0 comments on commit 718756b

Please sign in to comment.