programing

계산 속성 내에서 window.innerWidth를 사용하는 방법 - NuxtJs

prostudy 2022. 6. 30. 23:05
반응형

계산 속성 내에서 window.innerWidth를 사용하는 방법 - NuxtJs

는 nuxt프로젝트를 nuxt.js 에서는 nuxt.js의 .여기서 nuxt.js 내의 스타일을 결정해야 합니다.computed 하여 신청하다div screen size다음 예시와 같습니다.

기본적인 예

<template>
  <div :style="css"></div>
</template>

<script>
export default {
  computed: {
    css () {
      let width = window.innerWidth

      // ... mobile { ... styles }
      // ... desktop { ... styles }

      // ... if width is less than 700, return mobile
      // ... if width greater than 700, return desktop
    }
  }
}
</script>

실제의 예

<template>
  <div :style="css">
    <slot />
  </div>
</template>

<script>
export default {
  props: {
    columns: String,
    rows: String,
    areas: String,
    gap: String,
    columnGap: String,
    rowGap: String,
    horizontalAlign: String,
    verticalAlign: String,
    small: Object,
    medium: Object,
    large: Object
  },
  computed: {
    css () {
      let small, medium, large, infinty

      large = this.generateGridStyles(this.large)
      medium = this.generateGridStyles(this.medium)
      small = this.generateGridStyles(this.small)
      infinty = this.generateGridStyles()

      if (this.mq() === 'small' && this.small) return Object.assign(infinty, small)

      if (this.mq() === 'medium' && this.medium) return Object.assign(infinty, medium)

      if (this.mq() === 'large' && this.large) return Object.assign(infinty, large)

      if (this.mq() === 'infinty') return infinty

    }
  },
  methods: {
    generateGridStyles (options) {
      return {
        'grid-template-columns': (options !== undefined) ? options.columns : this.columns,
        'grid-template-rows': (options !== undefined) ? options.rows : this.rows,
        'grid-template-areas': (options !== undefined) ? options.areas : this.areas,
        'grid-gap': (options !== undefined) ? options.gap : this.gap,
        'grid-column-gap': (options !== undefined) ? options.columnGap : this.columnGap,
        'grid-row-gap': (options !== undefined) ? options.rowGap : this.rowGap,
        'vertical-align': (options !== undefined) ? options.verticalAlign : this.verticalAlign,
        'horizontal-align': (options !== undefined) ? options.horizontalAlign : this.horizontalAlign,
      }
    },
    mq () {
      let width = window.innerWidth

      if (width < 600) return 'small'
      if (width > 600 && width < 992) return 'medium'
      if (width > 992 && width < 1200) return 'large'
      if (width > 1200) return 'infinty'
    }
  }
}
</script>

<style lang="scss" scoped>
div {
  display: grid;
}
</style>

의 making GridLayout포트페페페페페vvvv표v표.vue다다다다다다vv

<template>
  <GridLayout
    columns="1fr 1fr 1fr 1fr"
    rows="auto"
    gap="10px"
    verital-align="center"
    :small="{
      columns: '1fr',
      rows: 'auto auto auto auto',
    }"
  >
    <h1>1</h1>
    <h1>2</h1>
    <h1>3</h1>
    <h1>3</h1>
  </GridLayout>
</template>

<script>
import { GridLayout } from '@/components/bosons'

export default {
  layout: 'blank',
  components: {
    GridLayout
  },
}
</script>


<style lang="scss" scoped>
h1 {
  background: #000;
  color: #fff;
}
</style>

합니다.windows is note definedif (this.mq() === 'small')

은 꼭 .pure Vue.js하지만 서버 사이드 렌더링이기 때문에 Nuxt.js에서는 동작하지 않는 것은 이해했습니다만, 어떻게 하면 동작시킬 수 있을까요?

내가 가장 가까이 접근한 것은 스타일 코드를 이동시키는 것이었다.mounted 방법if (process.client) {...}, 그 중 이든 특정 할 수 delay,jump예를 들어 다음과 같습니다.

process.client와 process.client를 비교합니다.

레이아웃에서 점프/지연(사용 시 process.client 조건)

어떻게 하면 지체 없이 일을 할 수 있을까요?Vue.js의 기본 동작을 마운트하기 전에 화면 폭을 어떻게 설정할 수 있습니까?

Nuxt 프레임워크가 윈도 오브젝트가 없는 서버 측에서 계산을 시도하고 있기 때문일 수 있습니다..process.client:

export default {
  computed: {
    css () {
      if (process.client) {
        let width = window.innerWidth

        // ... mobile { ... styles }
        // ... desktop { ... styles }

        // ... if width is less than 700, return mobile
        // ... if width greater than 700, return desktop
      } else {
        return { /*empty style object*/ }
      }
    }
  }
}

, '해키'라고 하면 null을 할 수 .window는 사용할 수 없으며 계산된 속성을 사용할 수 있게 되면 표시됩니다.문제의 근본 원인은 다음 DOM 업데이트 시 스타일이 적용되기 때문에 표시되기 전에 지연이 발생할 수 있습니다.

<template>
    <div :style="css" v-show="css">
    </div>
</template>

<script>
export default {
  computed: {
    css () {
      if (process.client) {
        let width = window.innerWidth

        // ... mobile { ... styles }
        // ... desktop { ... styles }

        // ... if width is less than 700, return mobile
        // ... if width greater than 700, return desktop
      } else {
        return null
      }
    }
  }
}
</script>

또는 다음 DOM 업데이트 시 css가 적용되므로 Vue에서 데이터 속성을 사용할 수 있습니다.$nextTick() (단, 기본적으로는 동일) :

<template>
    <div :style="css" v-show="reveal">
    </div>
</template>

<script>
export default {
  data() {
    return {
      reveal: false
    }
  },
  computed: {
    css () {
      if (process.client) {
        let width = window.innerWidth

        // ... mobile { ... styles }
        // ... desktop { ... styles }

        // ... if width is less than 700, return mobile
        // ... if width greater than 700, return desktop
      } else {
        return { /*empty style object*/ }
      }
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.reveal = true
    });
  }
}
</script>

다만, 질문에 의하면, 응답형 레이아웃을 적용하고 싶은 것 같습니다.가장 좋은 방법은 하는 것이다.scope을 너의 this에 넣어라.style태그를 지정하고 css 브레이크 포인트를 사용합니다.이렇게 하면 지연 문제가 해결되고 스타일과 논리가 분리됩니다.

<template>
    <div class="my-responsive-component">
    </div>
</template>

<script>
export default {
  computed: { /* nothing to see here! */ }
}
</script>

<style lang="css" scoped>
.my-responsive-component {
    height: 100px;
    width: 100px;
}

@media only screen and (max-width: 700px) {
    .my-responsive-component { background: yellow; }
}

@media only screen and (min-width: 700px) {
    .my-responsive-component { background: cyan; }
}
</style>

참고로 계산된 속성에는 적절한 if/else 문을 모두 사용합니다. 등의 if (!process.client) return { /* empty style object */}Vue 계산 속성에 예기치 않은 동작이 발생할 수 있습니다.

아래 github에 기재된 바와 같이 서버 렌더링으로 인해 발생하는 오래된 문제입니다.

.vue 파일

<script>
if (process.browser) {
  require('aframe')
}
export default {

}
</script>

nuxt.config.config.syslog

  build: {
    vendor: ['aframe']
  }

레퍼런스:
https://github.com/nuxt/nuxt.js/issues/30#issuecomment-264348589
https://nuxtjs.org/faq/window-document-undefined/

언급URL : https://stackoverflow.com/questions/57101714/how-to-use-window-innerwidth-within-computed-property-nuxtjs

반응형