效果图:
方案一:
<n-grid
cols="4"
item-responsive
responsive="self"
:x-gap="10"
:y-gap="10"
>
<n-grid-item span="4 400:2 600:2 800:1" class="light-green">
<div>内容<br/>内容<br/>内容<br/>内容<br/></div>
</n-grid-item>
<n-grid-item span="4 400:2 600:2 800:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 400:2 600:2 800:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 400:2 600:2 800:1" class="light-green"><div>内容</div></n-grid-item>
</n-grid>
方案二:
<n-grid
cols="4"
item-responsive
responsive="screen"
:x-gap="10"
:y-gap="10"
>
<n-grid-item span="4 m:2 l:1" class="light-green">
<div>内容<br/>内容<br/>内容<br/>内容<br/></div>
</n-grid-item>
<n-grid-item span="4 m:2 l:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 m:2 l:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 m:2 l:1" class="light-green"><div>内容</div></n-grid-item>
</n-grid>
完整代码:
<!-- 说明:此为响应式栅格布局,组件内只接受n-grid-item标签 -->
<!-- 使用示例:
<n-grid-item span="4 400:2 600:2 800:1" class="light-green"><div>内容</div></n-grid-item>
参数说明:见下 -->
<template>
<div class="grid_wrap">
<div v-if="responsivetype === 'self'">
<n-tag>自适应方案一:有4种尺寸</n-tag><br/>
1、开启响应式 item-responsive: true<br/>
2、设置显示栅格数量(即每行展示几个格)<br/>
3、开启根据自身宽度进行响应式布局,默认就是此模式responsive='self'<br/>
4、设置子元素响应式<br/>
0 - 400px 1/4<br/>
400px - 600px 1/2<br/>
600px - 800px 1/2<br/>
800px以上 1/1
</div>
<div v-else>
<n-tag>自适应方案二:有3种尺寸</n-tag><br/>
1、开启响应式 item-responsive: true<br/>
2、设置显示栅格数量(即每行展示几个格)<br/>
3、开启根据屏幕断点进行响应式布局responsive='screen'<br/>
4、设置子元素响应式<br/>
m以下 1/4<br/>
m - l 1/2<br/>
l及以上 1/1
</div>
<n-grid
cols="4"
item-responsive
:responsive="responsivetype"
:x-gap="10"
:y-gap="10"
>
<slot name="dom"></slot>
<!-- 方式一
<n-grid-item span="4 400:2 600:2 800:1" class="light-green">
<div>内容<br/>内容<br/>内容<br/>内容<br/></div>
</n-grid-item>
<n-grid-item span="4 400:2 600:2 800:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 400:2 600:2 800:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 400:2 600:2 800:1" class="light-green"><div>内容</div></n-grid-item> -->
<!-- 方式二
<n-grid-item span="4 m:2 l:1" class="light-green">
<div>内容<br/>内容<br/>内容<br/>内容<br/></div>
</n-grid-item>
<n-grid-item span="4 m:2 l:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 m:2 l:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 m:2 l:1" class="light-green"><div>内容</div></n-grid-item> -->
</n-grid>
</div>
</template>
<script lang="ts" setup>
defineProps<{
responsivetype: string | 'self'
}>()
</script>
<style lang="scss" scoped>
.grid_wrap {
width: 100%;
height: 100%;
}
</style>
使用示例:
<template>
<div class="app_box">
<Gird :responsivetype="info.responsivetype">
<!-- 方式一 -->
<template #dom v-if="info.responsivetype === 'self'">
<n-grid-item span="4 400:2 600:2 800:1" class="light-green">
<div>内容<br/>内容<br/>内容<br/>内容<br/></div>
</n-grid-item>
<n-grid-item span="4 400:2 600:2 800:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 400:2 600:2 800:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 400:2 600:2 800:1" class="light-green"><div>内容</div></n-grid-item>
</template>
<!-- 方式二 -->
<template #dom v-else>
<n-grid-item span="4 m:2 l:1" class="light-green">
<div>内容<br/>内容<br/>内容<br/>内容<br/></div>
</n-grid-item>
<n-grid-item span="4 m:2 l:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 m:2 l:1" class="light-green"><div>内容</div></n-grid-item>
<n-grid-item span="4 m:2 l:1" class="light-green"><div>内容</div></n-grid-item>
</template>
</Gird>
</div>
</template>
<script setup lang="ts">
import { defineAsyncComponent, reactive } from 'vue'
const Gird = defineAsyncComponent(() => import('./components/Gird.vue'))
interface Info<T> {
responsivetype: T
}
const info: Info<any> = reactive({
responsivetype: 'screen' // self / screen
})
</script>
<style lang="scss" scoped>
.app_box {
width: 100%;
height: 100%;
.light-green {
background-color: greenyellow;
}
}
</style>