服务器端和客户端渲染后如何操作DOM?
How to manipulate DOM both after server-side and client-side rendering?
这是我的代码(它是 Nuxt 应用程序中的一个 Vue 组件):
<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>
你在“mounted”函数中看到的是用来动态改变文本区域的高度的。当组件在客户端呈现时(即从另一个页面导航时),它可以正常工作,但应用程序在 SSR 后崩溃(当直接打开带有组件的页面时)。如何使该代码在这两种情况下都能正常工作?
您应该使用动态样式而不是直接 DOM 操作。
例如,<textare :style="{ height: computedHeight }" />
见https://vuejs.org/v2/guide/class-and-style.html#Object-Syntax-1
问题在于,当安装组件时,最初 class="leftside" 元素不是 dom 的一部分(由于 loggedIn 等于 false)。解决方案是将 class="leftside" 元素和 mounted() 函数移动到单独的组件。
这是我的代码(它是 Nuxt 应用程序中的一个 Vue 组件):
<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>
你在“mounted”函数中看到的是用来动态改变文本区域的高度的。当组件在客户端呈现时(即从另一个页面导航时),它可以正常工作,但应用程序在 SSR 后崩溃(当直接打开带有组件的页面时)。如何使该代码在这两种情况下都能正常工作?
您应该使用动态样式而不是直接 DOM 操作。
例如,<textare :style="{ height: computedHeight }" />
见https://vuejs.org/v2/guide/class-and-style.html#Object-Syntax-1
问题在于,当安装组件时,最初 class="leftside" 元素不是 dom 的一部分(由于 loggedIn 等于 false)。解决方案是将 class="leftside" 元素和 mounted() 函数移动到单独的组件。