Accessing Utils.dom.width and Utils.dom.height



  • Hi,

    I need to calculate heights for a group of cards contained in a row wrap. Each effective row´s cards should have the same height.
    So my approach was to emit an event in the card-containing component (parent) when it has been mounted passing the card´s computed height (using Utils.dom.height) as the event. Afterwards I am adjusting the styles in the parent component for each row´s cards. Here is the code:

    Parent component

    <div class="row gutter wrap">
      <div v-for="(result, index) in results" class="width-1of2">
        <recipe-card :recipe="result" :max-width="cardWidth" :style="cardStyle[index]" @mounted="computeMinHeight(index, $event)"/>
      </div>
    </div>
    
    data () {
      return {
      rowHeights: Array.from({length: 50}, x => 1)
      }
    },
    methods: {
      computeMinHeight (index, newHeight) {
        console.log('Found card: ' + index + ' with height: ' + newHeight)
        let rowIndex = Math.trunc(index / 2)
        this.rowHeights.splice(rowIndex, 1, Math.max(this.rowHeights[rowIndex], newHeight))
        console.log('Set height: ' + this.rowHeights[rowIndex] + ' for row ' + rowIndex)
      }
    },
    

    Child component

    mounted () {
      setTimeout(function () {
        this.$emit('mounted', Utils.dom.height(this.$el))
      }.bind(this), 100)
      // this.$nextTick(function () {
        // this.$emit('mounted', Utils.dom.height(this.$el))
      // })
    },
    

    Using this.$nextTick did not work because Utils.dom.height(this.$el) returned smaller heights. So I tried using setTimeout to overcome this problem and in fact it works, but it´s not a nice solution imo.
    I also have other situations were I would like to retrieve an element´s height or width after mounting, but I don´t know where the correct place is. I tried using the mounted() point but sometimes the values returned are too small and still increasing over time.
    And finally in some cases Utils.dom.weight(this.$el) ends with an error message saying, that this.$el is undefined while it is called in mounted() point. And by now I thought mounted() should be the correct place/time for that.

    I know these are probably different issues but I think they are very much related, so maybe someone has got some answers for me or can tell me how I can accomplish what I am aiming to do.

    Thanks,
    Tony



  • Hi,
    Your approach seems very complicated. If what you want to achieve is cards with equal height, here’s an excerpt from a conversation today on gitter that may provide useful inspiration.


    to get a q-card to behave in a flex grid, with variable height compensated by stretching (and a bonus 0.13-style button across zones), the following code works fine (note the css helper classes on q-card, no extra css needed)

    <template>
      <div class="row lg-gutter items-stretch">
        <template v-for="(item, index) in myList">
          <div class="col-4">
            <q-card class="full-height no-margin">
              <q-card-title>
                {{ item.name }}
              </q-card-title>
              <q-card-media>
                <img src="placeholder.png" height="120px">
              </q-card-media>
              <q-card-separator />
              <q-card-main class="relative-position">
                <q-btn round color="primary" small icon="place" class="absolute on-left" style="top: 0; right: 0px; transform: translateY(-57%);" />
                comment
                {{ item.comment }}
              </q-card-main>
            </q-card>
          </div>
        </template>
      </div>
    </template>
    


  • and this version has the title expand to take the extra space (instead of having whitespace at the bottom of cards)

    <template>
      <div class="layout-padding row md-gutter items-stretch">
        <template v-for="(item, index) in dailyList">
          <div class="col-sm-4">
            <q-card class="full-height no-margin" style="display: flex; flex-direction: column;">
              <q-card-title style="flex-grow: 1">
                {{ item.name }}
              </q-card-title>
              <q-card-media>
                <img src="placeholder.png" height="120px">
              </q-card-media>
              <q-card-separator />
              <q-card-main class="relative-position">
                <q-btn round color="primary" small icon="place" class="absolute on-left" style="top: 0; right: 0px; transform: translateY(-57%);" />
                comment
                {{ item.comment }}
              </q-card-main>
            </q-card>
          </div>
        </template>
      </div>
    </template>
    

Log in to reply
 

Looks like your connection to Quasar Framework was lost, please wait while we try to reconnect.