定制样式
默认样式
组件提供一个默认样式,你如果你喜欢可以直接引入 import 'bin-grid-layout/dist/styles/default.css'
<template>
<div class="container">
<b-grid-layout
v-model:layout="state.layout"
:col-num="12"
:row-height="30"
:is-draggable="state.draggable"
:is-resizable="state.resizable"
:vertical-compact="true"
:use-css-transforms="true"
>
<b-grid-item
v-for="(item, index) in state.layout"
:key="index"
:static="item.static"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
>
<span class="text">{{ itemTitle(item) }}</span>
</b-grid-item>
</b-grid-layout>
</div>
</template>
<script setup>
import { reactive } from 'vue'
const state = reactive({
layout: [
{ x: 0, y: 0, w: 2, h: 2, i: '0', static: false },
{ x: 2, y: 0, w: 2, h: 4, i: '1', static: true },
{ x: 4, y: 0, w: 2, h: 5, i: '2', static: false },
{ x: 6, y: 0, w: 2, h: 3, i: '3', static: false },
{ x: 8, y: 0, w: 2, h: 3, i: '4', static: false },
{ x: 10, y: 0, w: 2, h: 3, i: '5', static: false },
{ x: 0, y: 5, w: 2, h: 5, i: '6', static: false },
{ x: 2, y: 5, w: 2, h: 5, i: '7', static: false },
{ x: 4, y: 5, w: 2, h: 5, i: '8', static: false },
{ x: 6, y: 3, w: 2, h: 4, i: '9', static: true },
{ x: 8, y: 4, w: 2, h: 4, i: '10', static: false }
],
draggable: true,
resizable: true,
index: 0
})
function itemTitle(item) {
let result = item.i
if (item.static) {
result += ' - Static'
}
return result
}
</script>
<style scoped>
.container {
}
</style>
修改占位符颜色
<template>
<div class="container">
<b-grid-layout
v-model:layout="state.layout"
:col-num="12"
:row-height="30"
:is-draggable="state.draggable"
:is-resizable="state.resizable"
:vertical-compact="true"
:use-css-transforms="true"
>
<b-grid-item
v-for="(item, index) in state.layout"
:key="index"
:static="item.static"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
>
<span class="text">{{ itemTitle(item) }}</span>
</b-grid-item>
</b-grid-layout>
</div>
</template>
<script setup>
import { reactive } from 'vue'
const state = reactive({
layout: [
{ x: 0, y: 0, w: 2, h: 2, i: '0', static: false },
{ x: 2, y: 0, w: 2, h: 4, i: '1', static: true },
{ x: 4, y: 0, w: 2, h: 5, i: '2', static: false },
{ x: 6, y: 0, w: 2, h: 3, i: '3', static: false },
{ x: 8, y: 0, w: 2, h: 3, i: '4', static: false },
{ x: 10, y: 0, w: 2, h: 3, i: '5', static: false },
{ x: 0, y: 5, w: 2, h: 5, i: '6', static: false },
{ x: 2, y: 5, w: 2, h: 5, i: '7', static: false },
{ x: 4, y: 5, w: 2, h: 5, i: '8', static: false },
{ x: 6, y: 3, w: 2, h: 4, i: '9', static: true },
{ x: 8, y: 4, w: 2, h: 4, i: '10', static: false }
],
draggable: true,
resizable: true,
index: 0
})
function itemTitle(item) {
let result = item.i
if (item.static) {
result += ' - Static'
}
return result
}
</script>
<style scoped>
.container {
:deep(.bin-grid-layout) {
background-color: #eee;
}
:deep(.bin-grid-item) {
&.vue-grid-placeholder {
background: red !important;
opacity: 0.2;
transition-duration: 100ms;
border: 2px dashed black;
z-index: 2;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
&:not(.vue-grid-placeholder) {
background: #ccc;
border: 1px solid black;
}
&.static {
background: #cce;
}
.text {
font-size: 24px;
text-align: center;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
height: 100%;
width: 100%;
}
.remove {
position: absolute;
right: 2px;
top: 0;
cursor: pointer;
}
}
}
</style>
综合示例
<template>
<div class="container">
<b-grid-layout
v-model:layout="state.layout"
:col-num="12"
:row-height="30"
:is-draggable="state.draggable"
:is-resizable="state.resizable"
:vertical-compact="true"
:use-css-transforms="true"
>
<b-grid-item
v-for="(item, index) in state.layout"
:key="index"
:static="item.static"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
>
<div class="item-box">
<span class="text">{{ itemTitle(item) }}</span>
</div>
</b-grid-item>
</b-grid-layout>
</div>
</template>
<script setup>
import { reactive } from 'vue'
const state = reactive({
layout: [
{ x: 0, y: 0, w: 2, h: 2, i: '0', static: false },
{ x: 2, y: 0, w: 2, h: 4, i: '1', static: true },
{ x: 4, y: 0, w: 2, h: 5, i: '2', static: false },
{ x: 6, y: 0, w: 2, h: 3, i: '3', static: false },
{ x: 8, y: 0, w: 2, h: 3, i: '4', static: false },
{ x: 10, y: 0, w: 2, h: 3, i: '5', static: false },
{ x: 0, y: 5, w: 2, h: 5, i: '6', static: false },
{ x: 2, y: 5, w: 2, h: 5, i: '7', static: false },
{ x: 4, y: 5, w: 2, h: 5, i: '8', static: false },
{ x: 6, y: 3, w: 2, h: 4, i: '9', static: true },
{ x: 8, y: 4, w: 2, h: 4, i: '10', static: false }
],
draggable: true,
resizable: true,
index: 0
})
function itemTitle(item) {
let result = item.i
if (item.static) {
result += ' - Static'
}
return result
}
</script>
<style scoped>
.container {
:deep(.bin-grid-layout) {
--item-radius: 8px;
background-color: #fafafa;
}
:deep(.bin-grid-item) {
&.vue-grid-placeholder {
background: #1677ff;
opacity: 0.2;
transition-duration: 200ms;
z-index: 2;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
&:not(.vue-grid-placeholder) {
box-shadow:
1em 1em 1em #d8dae0b1,
-0.35em -0.35em 1em #ffffff;
border: 1.5px solid #f2f3f7;
&:hover {
background-color: #d3ddf1;
border: 1.5px solid #1677ff;
}
}
&.static {
background: #cce;
}
}
.item-box {
padding: 8px;
.text {
font-size: 24px;
text-align: center;
margin: auto;
height: 100%;
width: 100%;
}
.remove {
position: absolute;
right: 2px;
top: 0;
cursor: pointer;
}
}
}
</style>
其他元素样式
如果仍不满足需求,可以参考全部样式,按需修改。
css
.bin-grid-item {
transition: all 200ms ease;
transition-property: left, top, right;
&.no-touch {
touch-action: none;
}
&.cssTransforms {
transition-property: transform;
left: 0;
right: auto;
&.render-rtl {
left: auto;
right: 0;
}
}
&.resizing {
opacity: 0.6;
z-index: 3;
}
&.vue-draggable-dragging {
transition: none;
z-index: 3;
}
&.vue-grid-placeholder {
background: red;
opacity: 0.2;
transition-duration: 100ms;
z-index: 2;
user-select: none;
}
> .vue-resizable-handle {
position: absolute;
width: 20px;
height: 20px;
bottom: 0;
right: 0;
/* background: none; */
background-position: bottom right;
padding: 0 3px 3px 0;
background-repeat: no-repeat;
background-origin: content-box;
box-sizing: border-box;
cursor: se-resize;
}
> .vue-rtl-resizable-handle {
bottom: 0;
left: 0;
/* background: none; */
background-position: bottom left;
padding-left: 3px;
background-repeat: no-repeat;
background-origin: content-box;
cursor: sw-resize;
right: auto;
}
&.disable-userselect {
user-select: none;
}
}