naive-ui自适应方案

1,460 阅读1分钟

效果图:

Video_2022-09-24_180056 00_00_00-00_00_30.gif

方案一:

<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>