Javascript 如何在computed属性-NuxtJS中使用window.innerWidth
我正在处理一个nuxt.js项目,在这个项目中,我需要确定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 //
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>