使用理由:这个瀑布流是可以拖拽的
在安装完这个插件之后,在IE上无法打开,并报错缺少:,最终是下面这篇文章解决问题
Vue项目下IE报错 SCRIPT1003: 缺少 ‘:’,导致页面空白的解决方案
主要原因就是第三方库的兼容性问题,把vue-grid-layout
引入到vue.config.js
文件下的transpileDependencies
集合中:
module.exports = {
...
transpileDependencies: ['element-ui', 'proxy-polyfill' , 'vue-grid-layout'],
}
我的需求值只需要显示3-4列的样子,所以我需要多少列就将col-num设为多少,便于后续的位置计算。这里的组件实现了对接收的数组进行构造,生成可供gird-layout使用的数据,最后返回拖拽调换后的顺序。
<template>
<grid-layout
:layout.sync="layout"
:col-num="colNum"
:row-height="rowHeight"
:is-draggable="isDraggable"
:is-resizable="isResizable"
:is-mirrored="isMirrored"
:margin="marginArr"
:responsive="isResponsive"
:useStyleCursor="true"
>
<grid-item
v-for="item in layout"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="item.i"
class="item"
drag-allow-from=".dragger"
@moved="movedEvent"
>
<!-- 將数据外传 -->
<slot name="item" :item="item"></slot>
</grid-item>
</grid-layout>
</template>
<script>
import * as _ from 'lodash'
import VueGridLayout from 'vue-grid-layout'
export default {
components: {
GridLayout: VueGridLayout.GridLayout,
GridItem: VueGridLayout.GridItem,
},
props: {
indData: {
type: Array,
default: () => [],
},
colNum: {
type: Number,
default: 3,
},
rowHeight: {
type: Number,
default: 100,
},
isDraggable: {
type: Boolean,
default: false
},
isResizable: {
type: Boolean,
default: false
},
isMirrored: {
type: Boolean,
default: false
},
isResponsive: {
type: Boolean,
default: false
},
marginArr:{
type: Array,
default: () => [10, 20],
},
// 根据这个键返回排序后的数组,如果不设置,就返回整个排序后的对象
sortKey:{
type:String,
default:''
}
},
data() {
return {
layout: [
{ x: 0, y: 0, w: 1, h: 1, i: '0', id: 1 },
{ x: 1, y: 0, w: 1, h: 1, i: '1', id: 2 },
{ x: 2, y: 0, w: 1, h: 1, i: '2', id: 3 },
{ x: 0, y: 1, w: 1, h: 1, i: '3', id: 4 },
{ x: 1, y: 1, w: 1, h: 1, i: '4', id: 5 },
],
}
},
methods: {
// 构造数据
createLayout(arr) {
const col = this.colNum
const res = arr.map((item, index) => {
item.x = index % col
item.y = parseInt(index / col)
item.w = 1
item.h = 1
item.i = index + ''
return item
})
return res
},
// 移动之后的事件
movedEvent(i, newX, newY) {
const arr = this.getMovedOrder().map((item) => {
if(!this.sortKey){
return item
}else{
return item[this.sortKey]
}
})
this.$emit('moved',arr)
},
getMovedOrder() {
const newLayout = [...this.layout]
// 先按y(行)排,再按x(列)排序
newLayout.sort((a, b) => {
if (a.y !== b.y) {
return a.y - b.y
} else {
return a.x - b.x
}
})
return newLayout
},
},
watch: {
indData:{
handler(arr) {
// 这里需要深拷贝,否则之后的操作会改变这个对象
this.layout = this.createLayout(_.cloneDeep(arr))
},
deep: true,
immediate:true
},
},
}
</script>
<style lang="scss" scoped>
.item {
touch-action: none;
width: 100%;
height:100%;
border: 1px solid #5592e5;
// transition: all .3s;
// cursor: move;
&:hover{
transform: scale(1.05,1.05);
}
}
</style>
需要设置响应式的话,就对cols进行相应设置,breakpoints直接使用默认即可
:responsive="true"
:cols="{ lg: 3, md: 2, sm: 2, xs: 1, xxs: 1 }"
:breakpoints="{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }"
<template>
<grid-fall :colNum="3" :rowHeight="100" :indData="indData" :isDraggable="true" @moved="getMovedData" :sortKey="'id'">
<template slot="item" slot-scope="data">
子组件循环中的值:{{data.item.i}}
<!-- button 无效 -->
<el-button class="dragger">拖动(实际无效)</el-button>
<el-button class="no-drag">不可拖动</el-button>
<p class="dragger">拖动图标(可拖动)</p>
</template>
</grid-fall>
</template>
<script>
import GridFall from '@/components/indicator/combine/GridFall.vue'
export default {
components:{
GridFall
},
data() {
return {
// 传入的对象数组
indData: [
{ id:0 },
{ id:1 },
{ id:2 },
{ id:3 },
{ id:4 },
{ id:5 },
]
}
},
methods:{
getMovedData(v){
console.log('拖拽排序之后:',v)
}
}
}
</script>