简体   繁体   中英

How to manipulate DOM both after server-side and client-side rendering?

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

<template>
  <div class="comment-editor" v-if="loggedIn">
    <div class="leftside">
      <!-- <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 class="notLoggedIn" 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 (ie 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?

You should use dynamic styling instead of direct DOM manipulations.

Eg, <textare:style="{ height: computedHeight }" />

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM