vue.js 不会在mounted() 挂钩上更新

Posted

技术标签:

【中文标题】vue.js 不会在mounted() 挂钩上更新【英文标题】:vue.js doesn't update on mounted() hook 【发布时间】:2018-10-13 23:54:24 【问题描述】:

编辑:已解决,请参阅答案。

所以我是 vue.js 和 quasar 的新手,所以这可能是关于 vue 生命周期钩子和 vue 反应性的新手错误。

我想根据浏览器的大小调整元素的大小。该元素的高度是使用其他元素的高度计算的。我使用 $refs 来获取另一个元素的高度,并捕获由 quasar 组件启动的 onResize() 事件。

该事件在页面加载时启动一次,我的元素的大小都是 0,因为我猜它们还没有在 DOM 中呈现。我有一个方法来刷新我的计算高度,当“onResize”事件被捕获时我会调用它,也可以在“mounted()”vue.js 钩子上调用。

我的问题是:

第一个 onResize() 调用该方法,但所有元素的高度均为 0px。 mounted() 再次调用该方法,在这里计算所有元素的高度。结果很好,但它没有显示在显示屏上,请参见屏幕截图 #1:调整控制台中记录的事件和大小,注意大小计算两次,一次在 onResize() 上,一次在 mount() 上。 mount() 上的那个有很好的价值,但它没有显示在 DOM 中。

在我调整窗口大小一次后,一切正常,我不再有任何问题。 (截图#2(窗口模式)和#3(再次全屏))

我的问题是:为什么调用mounted() 挂钩时DOM 中的高度没有更新,即使计算正确? (一切都在同一个 .vue 文件中)

我的代码: 我的问题是具有“tableRow”参考的 div 的高度

<template>
  <q-page>
    <div class="row" :style="'height: '+pageSize.height*0.95+'px;'">
      <div class="col-6 q-pa-lg">

        <div class="row" ref="actionsRow">
          <div class="col-6 q-mb-sm">
            <q-search hide-underline v-model="filter" />
          </div>
          <div class="col-6">

          </div>
        </div>

        <div class="row" ref="tableHeaderRow">
          <q-table class="col-12" :selection="selectionMode" :selected.sync="selectedRows" :data="templateTableData" :columns="templateColumns"
            row-key="slug" :pagination.sync="pagination" dense hide-bottom>
            <q-tr slot="body" slot-scope="props" :props="props">
            </q-tr>
          </q-table>
        </div>

        <div class="row" ref="tableRow" :style="'height: '+tableHeight+'px;'">
          <q-scroll-area style="height: 100%" class="col-12 q-mt-sm shadow-3">
            <q-table :selection="selectionMode" :selected.sync="selectedRows" :data="templateTableData" :columns="templateColumns" row-key="slug"
              :filter="filter" :pagination.sync="pagination" dense hide-bottom hide-header>
              <q-tr slot="body" slot-scope="props" :props="props" @click.native="onRowClick(props.row)" class="cursor-pointer">
                <q-td auto-width>
                  <q-checkbox color="primary" v-model="props.selected" />
                </q-td>
                <q-td v-for="col in props.cols" :key="col.name" :props="props">
                   col.value 
                </q-td>
              </q-tr>
            </q-table>
          </q-scroll-area>
        </div>

      </div>
      <router-view class="col-6 q-pa-lg">
      </router-view>
    </div>
    <q-window-resize-observable @resize="onResize" />
  </q-page>
</template>

脚本:

var data = []
for (var i = 1; i <= 100; i++) 
  data.push(
    id: i,
    name: 'Template ' + i,
    slug: 'template' + i,
    active: true
  )


import  mapActions, mapGetters  from 'vuex'

export default 
  data: () => (
    pageSize: 
      height: 0,
      width: 0
    ,
    tableHeight: 0,
    templateColumns: [
      
        name: 'templateName',
        required: true,
        label: 'Name',
        align: 'left',
        field: 'name',
        sortable: true
      ,
      
        name: 'templateSlug',
        label: 'Slug',
        align: 'left',
        field: 'slug',
        sortable: true
      ,
      
        name: 'templateActive',
        label: 'Active',
        align: 'left',
        field: 'active',
        sortable: true,
        sort: (a, b) => 
          if ((a && b) || (!a && !b)) 
            return 0
           else if (a) 
            return 1
           else 
            return -1
          
        
      
    ],
    selectionMode: 'multiple',
    selectedRows: [],
    pagination: 
      sortBy: null, // String, column "name" property value
      descending: false,
      page: 1,
      rowsPerPage: 0 // current rows per page being displayed
    ,
    templateTableData: data,
    filter: ''
  ),
  computed: 
    ...mapGetters('appUtils', [
      'getPageTitle',
      'allConst'
    ])
  ,
  methods: 
    ...mapActions('appUtils', [
      'setPageTitle',
      'deletePageTitle'
    ]),
    onResize (size) 
      this.pageSize.height = size.height - this.getPageTitle.height
      this.resizeTable()
      console.log('ON RESIZE EVENT:')
      console.log('tableHeaderRow:'+
          this.$refs.tableHeaderRow.clientHeight)
      console.log('actionsRow:' + this.$refs.actionsRow.clientHeight)
      console.log('table:' + this.tableHeight)
    ,
    onRowClick (row) 
      this.$router.push('/templates/' + row.slug)
    ,
    resizeTable () 
      this.tableHeight = this.pageSize.height - this.$refs.actionsRow.clientHeight -
          this.$refs.tableHeaderRow.clientHeight - this.getPageTitle.height -
          this.allConst.templatePageHeaderMargins
    
  ,
  mounted () 
    console.log('MOUNT TEMPLATES')
    this.setPageTitle( text: 'Manage templates', height: this.allConst.titleHeight )
    this.resizeTable()
    console.log('tableHeaderRow:' + this.$refs.tableHeaderRow.clientHeight)
    console.log('actionsRow:' + this.$refs.actionsRow.clientHeight)
    console.log('table:' + this.tableHeight)
  ,
  destroyed () 
    console.log('DESTROY TEMPLATES')
    this.deletePageTitle()
  

【问题讨论】:

【参考方案1】:

在第一个 onResize() 事件期间,我的另一个变量 (titleSize) 是 0,与其他大小一样,我没有考虑到在 mounted() 挂钩期间更正它。

【讨论】:

你不是白痴。这个领域的每个人都在不断地学习和提高。坚持下去并找出解决方案做得很好。

以上是关于vue.js 不会在mounted() 挂钩上更新的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 更新的属性不会在子组件上更改

vue.js中mounted和created的区别

Vue.js `mounted` 中是不是可以使用`async/await`?

vue.js $watch 对象数组

每次更新路由时调用一个函数 vue.js

Vue2.0 $set()的使用方法