Hello World
Hello World

Reputation: 83

Set element height based on parent height in vue js on page load

I want to set the height of a vue component (to be specific it is this -> https://github.com/jbaysolutions/vue-grid-layout).

The height of which (in vue-grid-layout -> grid-item) should be same as of its parent.

And this also should be only in page load time. So how this can be achieved in vue js?

I don't want to do this using CSS. I need height in pixels. as to vue-grid-layout -> item height needs in pixel initially. as it is resizable, it can be changed afterwards.

Upvotes: 2

Views: 20228

Answers (3)

Straticiuc Vicu
Straticiuc Vicu

Reputation: 122

I found a solution to fix the grid-layout height depending on available space. For that I have used folowing props: max-rows, row-height, margins, autoSize=false And ResizeObserver which will adjust grid-layout row-height according to available height after window resize. Also be aware that I used some Bootstrap classes for styling


<template>
  <div class="flex-grow-1 w-100">
    <grid-layout
      :layout="layout"
      :col-num="colCount"
      :maxRows="rowCount"
      :row-height="rowHeight"
      :autoSize="false"
      :is-draggable="true"
      :is-resizable="true"
      :is-mirrored="false"
      :preventCollision="true"
      :vertical-compact="false"
      :margin="margin"
      :use-css-transforms="true"
    >
      <grid-item
        v-for="item in layout"
        class="bg-primary"
        :x="item.x"
        :y="item.y"
        :w="item.w"
        :h="item.h"
        :i="item.i"
        :key="item.i"
      >
        <span class="remove" @click="removeItem(item.i)">x</span>
      </grid-item>
    </grid-layout>
  </div>
</template>

<script lang="ts">
import { defineComponent } from '@vue/runtime-core';

interface GridItem {
  x: number;
  y: number;
  w: number;
  h: number;
  i: string;
}

interface State {
  layout: GridItem[];
  index: number;
  colCount: number;
  rowCount: number;
  rowHeight: number;
  observer: null | ResizeObserver;
  margin: number[];
}

export default defineComponent({
  name: 'VideoWall',
  data(): State {
    return {
      layout: [
        { x: 0, y: 0, w: 2, h: 2, i: '0' },
        { x: 2, y: 0, w: 2, h: 4, i: '1' },
        { x: 4, y: 0, w: 2, h: 5, i: '2' },
        { x: 6, y: 0, w: 2, h: 3, i: '3' },
        { x: 8, y: 0, w: 2, h: 3, i: '4' },
      ],
      index: 0,
      colCount: 36,
      rowCount: 36,
      rowHeight: 40,
      margin: [5, 5],
      observer: null,
    };
  },
  mounted() {
    this.observer = new ResizeObserver(this.onResize);

    if (this.$el instanceof Element) {
      this.observer.observe(this.$el);
    } else {
      console.log('VideoWall: Failed to bind observer');
    }
  },
  unmounted() {
    if (this.observer) {
      this.observer.disconnect();
    }
  },
  methods: {
    onResize(entries: ResizeObserverEntry[]): void {
      this.rowHeight =
        Math.floor(entries[0].contentRect.height / this.rowCount) -
        this.margin[1];
    },
  },
});
</script>

Upvotes: 0

Borisu
Borisu

Reputation: 848

it would be easier to provide an accurate answer with some example html (your actual code), but the following should work in general.

export default {
    ...
    data() {
        return {
            parentHeight: 0
        }
    },
    mounted() {
        this.parentHeight = this.$parent.$el.offsetHeight;
    }
    ...
}

So in the mounted lifecycle hook you can read the height of the parent and then set it where ever you need it.

Upvotes: 5

Ferrybig
Ferrybig

Reputation: 18824

No need for advanced javascript to calculate the height, just use styling:

height: 100%;

Demo:

.parent {
    resize: both;
    overflow: auto;
    height: 100px;
    display: block;
    width: 100px;
    border: 1px solid black;
}

.child {
    height: 100%;
    background: pink;
}
<div class="parent">
</div>

<div class="parent">
    <div class="child">
         I'm a child!
    </div>
</div>

Upvotes: 0

Related Questions