首页 > 解决方案 > Vue.js:如何在不刷新的情况下更新布局

问题描述

我想要做的是在屏幕尺寸较小时使 Dialog 全屏。我现在的代码是这样的。

<v-dialog 
    max-width="600px"
    :fullscreen="screen_width < 450 ? true : false">

...

screen_width: screen.width

但是,除非用户刷新屏幕,否则当屏幕变小时,这种方式不会更新布局。

<v-dialog class="dialog">

@media only screen and (max-width: 450px)
.dialog {
    width: 100%;
    height: 100%;
}

我也尝试过这种方式,但这没有用。如何在不让用户刷新屏幕的情况下更改布局?

标签: vue.js

解决方案


而不是screen.width我更倾向于跟踪视口宽度,window.innerWidth.

下面的示例跟踪宽度和高度,并通过 Vue 原型上的反应对象公开它们。该对象可作为$viewport实例上的属性访问。resizeon 事件window用于监听视口大小的变化并相应地更新反应值。

如果您想在整个应用程序的多个位置使用视口大小,将其添加到原型中很有用。如果您只想在一个特定的地方使用它,那么您可以将大部分逻辑移到您的组件中。在这种情况下你不需要使用Vue.observable,而是你只需要一个适合data宽度的属性。当组件被销毁时,您还希望删除resize侦听器。

const updateSizes = (obj = {}) => {
  obj.width = window.innerWidth
  obj.height = window.innerHeight
  return obj
}

Object.defineProperty(Vue.prototype, '$viewport', {
  value: Vue.observable(updateSizes())
})

window.addEventListener('resize', () => {
  updateSizes(Vue.prototype.$viewport)
})

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  
  data () {
    return {
      dialog: true
    }
  }
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://unpkg.com/mdi@2.2.43/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://unpkg.com/vuetify@2.0.11/dist/vuetify.min.css" rel="stylesheet">
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify@2.0.11/dist/vuetify.min.js"></script>

<div id="app">
  <v-app>
    <v-dialog
      v-model="dialog"
      width="500"
      :fullscreen="$viewport.width < 450"
    >
      <v-card>
        <v-card-title
          class="headline grey lighten-2"
          primary-title
        >
          Title
        </v-card-title>

        <v-card-text>
          Body text
        </v-card-text>
      </v-card>
    </v-dialog>
  </v-app>
</div>


推荐阅读