Javascript 如何在computed属性-NuxtJS中使用window.innerWidth

Javascript 如何在computed属性-NuxtJS中使用window.innerWidth,javascript,vue.js,vuejs2,nuxt.js,Javascript,Vue.js,Vuejs2,Nuxt.js,我正在处理一个nuxt.js项目,在这个项目中,我需要确定computed属性中的样式,并基于屏幕大小应用于div,如下例所示: 基本示例 <template> <div :style="css"></div> </template> <script> export default { computed: { css () { let width = window.innerWidth //

我正在处理一个nuxt.js项目,在这个项目中,我需要确定
computed
属性中的样式,并基于
屏幕大小
应用于
div
,如下例所示:

基本示例

<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>
不起作用,它会生成一个错误
如果
(this.mq()=“small”)

这在
pure Vue.js
中非常有效,但我知道它在Nuxt.js上不起作用,因为它是服务器端渲染,这非常有意义,但我如何才能让它工作呢

我得到的最接近的方法是将样式代码移动到装入的
方法中,或者将样式代码包装到
if(process.client){…}
,但是任何替代方法都会在内容中产生一定的
延迟
跳转
,例如:


我怎样才能使它毫不拖延地工作?如何在安装Vue.js的默认行为之前获得屏幕宽度?

这是一个由于服务器渲染而出现的老问题,如github上的以下问题所述

.vue文件

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

}
</script>
参考资料:


我怀疑这是因为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,并在计算属性可用时显示。在它变得可见之前,您仍然会有一个延迟,因为问题的根源是在下一次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>

顺便说一句,作为旁注,对计算属性使用适当的if/else语句。使用诸如
if(!process.client)return{/*empty style object*/}
之类的方法有时会在Vue计算属性中产生一些意外行为。

我对其进行了测试,它正常工作,但由于
if(process.client)
的原因,它会延迟应用样式,当样式逻辑位于
mountd
中时也是如此。。我需要在到达安装的
之前准备好样式。我试过了,但代码似乎不完整,我无法让它工作,你能帮我吗?我没有使用store,我想将其存储在全局函数中,例如,
this.$mq
,从您的问题来看,您似乎只是想要一个响应性布局。最好的选择是直接将断点写入css中,而不是让样式依赖于计算属性。。。这不是你的选择吗?还有其他/更好的选择,但我不确定您的项目是如何设置的,或者您的目标是什么。在这种情况下,不,因为它是一个可重用的组件,很快样式化将是动态的,并且将具有一定的复杂性,以至于仅分配CSS类无法解决问题,需要用脚本完成。我的直觉告诉我这不是正确的方法,但我不知道你在构建什么,所以我相信你!:)关于延迟,我想您可以在下一个刻度上设置computed属性后立即显示。。。这有点“黑”,但它可能会工作。我将编辑我的答案我真的很高兴能帮助我:)我测试过了,它又能工作了,但仍然有延迟,只是有所不同。如果仅使用
If(process.client)
它将显示未受压力的内容,并延迟应用样式。如果使用
If(process.client)
v-show=“css”
一起使用,则仅当样式就绪时才会显示div,但与其他div/DOM相比仍有延迟。简言之,延迟问题仍然存在
  build: {
    vendor: ['aframe']
  }
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*/ }
      }
    }
  }
}
<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>
<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>
<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>