vue 指令实现网格排布
效果图
使用方式
<template>
<div class="box">
<h4>单一网格布局参数</h4>
<div class="inner-main" v-Grid="obj" id="ss">
<div class="inner" v-for="(item, index) in list" :key="index">
{{ item.name }}
</div>
</div>
<h4>错乱网格布局参数</h4>
<div class="inner-main" v-Grid="ary" id="ss">
<div class="inner" v-for="(item, index) in list" :key="index">
{{ item.name }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
{ name: "b" },
],
obj: {
il: 10,
bn: 3,
mb: 12,
},
ary: [
{ sx: 1, ex: 3, bn: 3, il: 10, mb: 5 },
{ sx: 4, ex: 5, bn: 2, il: 15, mb: 10 },
{ sx: 6, ex: 7, bn: 2, il: 30, mb: 10 },
{ sx: 8, ex: 12, bn: 3, il: 20, mb: 20 },
{ sx: 13, ex: 14, bn: 2, il: 20, mb: 20 },
],
};
},
};
</script>
<style scoped lang="scss">
.box {
width: 500px;
background: #eee;
border: 1px solid red;
padding: 20px;
}
.inner-main {
margin-bottom: 50px;
}
.inner {
height: 40px;
line-height: 40px;
text-align: center;
font-size: 20px;
font-weight: bold;
background: yellow;
}
h4 {
margin-bottom: 12px;
}
</style>
v-Grid配置
v-Grid
** 所有参数字段均为number
v-Grid="obj" 单一网格布局参数
obj = {
bn: "行内格子数量",
il: "行内间隔",
mb: "行间隔"
}
v-Grid="ary" 错乱网格布局参数
ary = [
{
sx: "起始盒子坐标",
ex: "终止盒子坐标",
bn: "行内格子数量",
il: "行内间隔",
mb: "行间隔",
}
]
实现方式源码 (需要在main.js引用)
import Vue from "vue";
const arrangement = (el, self) => {
el.style.display = "flex";
el.style.flexWrap = "wrap";
el.style.alignContent = "flex-start";
if (Array.isArray(self.value)) {
self.value.forEach((v, aryIndex) => {
setTimeout(() => {
const { sx, ex, il, bn, mb } = v;
const nodeList = el.childNodes;
let g = Math.ceil((ex - sx + 1) / bn);
let si = g * bn - bn;
const nnl = [];
nodeList.forEach((node, index) => {
let nodeIndex = index + 1;
if (nodeIndex >= sx && nodeIndex <= ex) {
nnl.push(node);
}
});
nnl.forEach((node, index) => {
const width = el.getBoundingClientRect().width;
const ilSum = (bn - 1) * il;
const bnWidth = (width - ilSum) / bn;
node.style.width = `${bnWidth}px`;
if ((index + 1) % bn !== 0) {
node.style.marginRight = `${il}px`;
}
node.style.marginBottom = `${mb}px`;
if (aryIndex == self.value.length - 1 && index >= si) {
node.style.marginBottom = `0px`;
}
});
}, 1);
});
} else {
const { il, bn, mb } = self.value;
const width = el.getBoundingClientRect().width;
const ilSum = (bn - 1) * il;
const bnWidth = (width - ilSum) / bn;
setTimeout(() => {
const nodeList = el.childNodes;
let g = Math.ceil(nodeList.length / bn);
let si = g * bn - bn;
nodeList.forEach((node, index) => {
node.style.width = `${bnWidth}px`;
if ((index + 1) % bn !== 0) {
node.style.marginRight = `${il}px`;
}
if (index < si) {
node.style.marginBottom = `${mb}px`;
}
});
}, 1);
}
};
// v-Grid
/**
* v-Grid
* ** 所有参数字段均为number
*
* v-Grid="obj" 单一网格布局参数
* obj = {
* bn: "行内格子数量",
* il: "行内间隔",
* mb: "行间隔"
* }
*
* v-Grid="ary" 错乱网格布局参数
* ary = [
* {
* sx: "起始盒子坐标",
* ex: "终止盒子坐标",
* bn: "行内格子数量",
* il: "行内间隔",
* mb: "行间隔",
* }
* ]
*
*/
Vue.directive("Grid", {
inserted: function (el, self) {
arrangement(el, self);
},
update: function (el, self) {
arrangement(el, self);
},
});
本文链接:
/archives/rq5IkAdm
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
Polaris!
喜欢就支持一下吧