我如何在vue js中引用body标签“正确的方式”

问题描述 投票:0回答:2

我的布局文件中包含以下代码和我的 appSearch 组件:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" type="text/css" href="css/app.css" />
        <title>title</title>
    </head>
    <body>
        <div id ='app' >
            <app-search ref='search'></app-search>
            @include('layouts/header')
            @yield('content')
        </div>
        <script type="text/javascript" src="js/app.js" ></script>
    </body>
</html>

在组件中,我想引用 body 标签并为其设置一些将应用溢出:隐藏的类。但是vue不能在div之外使用。我首先想到的是 document.querySelector。但这不是“vue-ish”的方式。有什么办法可以解决吗?

javascript vue.js
2个回答
14
投票

正如您提到的,您无法使用 Vue 访问 body 标签,而是使用常规 JavaScript 访问。如果您正在操作 DOM,您需要确保模板已呈现,然后您可以访问 HTML 元素,例如在

mounted()
中,但是
<body>
此时已经渲染,您的 Vue 应用程序正在运行。因此,您可以使用
document.querySelector
(或者更简单地使用评论中提到的
document.body
)来访问
<body>
标签。

通常不需要直接在 Vue 应用程序中访问 body 标签。您通常可以通过 Vueish 方式实现相同的目标。在您的情况下,您可以将一个类放置到 Vue 应用程序的最高元素(

App.vue
)上,并让该元素充当您的
<body>
。然后,您就可以使用 Vue 完全控制模板。

如果您使用的是 Vue 3 并且需要在 Vue 应用程序的最高元素之外有一个托管元素,您还可以使用新的

<teleport>
标签。这是例如用于模式叠加,但它不会帮助您向 body 元素添加类。请参阅 文档了解
<teleport>


0
投票

直接从我的代码中删除示例。有用的一点是

addBodyClass
removeBodyClass

// App.vue
<script setup lang="ts">
import {useGlobalState} from "@/composables/store";
import {watch} from "vue";
const {isDark} = useGlobalState()

// Update bodyClass based on isDark
watch(isDark, (newValue) => {
  if (newValue) addBodyClass('dark')
  else removeBodyClass('dark')
})


// Functions to manipulate <body> classes
const addBodyClass = (className: string) => {
  document.body.classList.add(className)
}

const removeBodyClass = (className: string) => {
  document.body.classList.remove(className)
}

</script>

<template>
  <div id="app">
    <RouterView />
  </div>
</template>
© www.soinside.com 2019 - 2024. All rights reserved.