Home > Back-end >  How to manipulate DOM both after server-side and client-side rendering?
How to manipulate DOM both after server-side and client-side rendering?

Time:12-24

Here is my code (it is a Vue component in a Nuxt app):

<template>
  <div  v-if="loggedIn">
    <div >
      <!-- <client-only> -->
      <textarea
        ref="editor"
        v-model="content"
        placeholder="your comment"
      ></textarea>
      <!-- </client-only> -->
      <Message v-bind="message" />
    </div>
    <Button
      text="Publish"
      color="main"
      v-if="message.type != 'loading'"
      @click="publish"
    />
  </div>
  <div  v-else>
    You should <nuxt-link to="/signup">register</nuxt-link> or
    <nuxt-link to="/login">log in</nuxt-link> to write comments.
  </div>
</template>

<script>
export default {
  data() {
    return {
      content: "",
    };
  },
  mounted() {
    const tx = document.querySelector("textarea");
    fh(tx);
    tx.style.overflowY = "hidden";
    tx.addEventListener("input", function () {
      fh(this);
    });
    function fh(x) {
      while (x.style.height   "" != x.scrollHeight   "px")
        x.style.height = x.scrollHeight   "px";
    }
  },
};
</script>

What you can see in the "mounted" function is used to dynamically change the height of a textarea. It works properly when the component is client-side rendered (i.e. when navigating from another page), but the app crashes after SSR (when directly opening the page with the component). How to make that code work properly in both cases?

CodePudding user response:

You should use dynamic styling instead of direct DOM manipulations.

E.g., <textare :style="{ height: computedHeight }" />

See https://vuejs.org/v2/guide/class-and-style.html#Object-Syntax-1

CodePudding user response:

The problem was that when the component was mounted, initially, the element was not part of the dom (due to loggedIn being equal to false). The solution was to move the element and the mounted() function to a separate component.

  • Related