界面响应式

兮城

关注

阅读 87

2023-06-28

界面响应式

1.封装

//-- media-query.js
const Breakpoints = {
 XSmall: "(max-width: 699.99px)",
 Small: "(min-width: 700px) and (max-width: 959.99px)",
 Medium: "(min-width: 960px) and (max-width: 1279.99px)",
 Large: "(min-width: 1280px)",
}

let handlers = []
const xSmallMedia = window.matchMedia(Breakpoints.XSmall)
const smallMedia = window.matchMedia(Breakpoints.Small)
const mediumMedia = window.matchMedia(Breakpoints.Medium)
const largeMedia = window.matchMedia(Breakpoints.Large)

;[xSmallMedia, smallMedia, mediumMedia, largeMedia].forEach(media => {
 media.addListener(() => {
   handlers.forEach(handler => handler())
 })
})

export const sizes = () => {
 return {
   "screen-x-small": xSmallMedia.matches,
   "screen-small": smallMedia.matches,
   "screen-medium": mediumMedia.matches,
   "screen-large": largeMedia.matches,
 }
}

export const subscribe = handler => handlers.push(handler)

export const unsubscribe = handler => {
 handlers = handlers.filter(item => item !== handler)
}

2.使用

<template>
  <div class="wrap">

  </div>
</template>

<script>
import { sizes, subscribe, unsubscribe } from "@/utils/media-query"
function getScreenSizeInfo() {
  const screenSizes = sizes()
  return {
    isXSmall: screenSizes["screen-x-small"],
    isLarge: screenSizes["screen-large"],
    cssClasses: Object.keys(screenSizes).filter(cl =>screenSizes[cl]),
  }
}
export default {
  name: "Layout",
  data() {
    return {
      screen: getScreenSizeInfo(),
    }
  },
  methods: {
    screenSizeChanged() {
      this.screen = getScreenSizeInfo()
      this.$store.commit("setScreenSize", this.screen)
    },
  },
  watch: {
    screen: {
      handler(val) {
        // 存在store中并持久化
        this.$store.commit("setScreenSize", val)
      },
      immediate: true,
    },
  },
  mounted() {
    subscribe(this.screenSizeChanged)
  },
  beforeDestroy() {
    unsubscribe(this.screenSizeChanged)
  },
}
</script>

<style lang="scss" scoped>
</style>

精彩评论(0)

0 0 举报