I have this code in my layout file with my appSearch component:
<!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>
In the component I want to reference body tag and set it some class that will apply overflow: hidden. However vue can't be used outside div. The first thing that came to my mind is document.querySelector. But it's not 'vue-ish' way of doing this. Is there any way around it?
You cannot access the body tag with Vue, but with regular JavaScript, as you mentioned. If you are manipulating the DOM you need to make sure, that the template is rendered and you can then access the HTML element e.g. in mounted(), but the <body> is already rendered at the time, your Vue app is running. So you can just use document.querySelector (or more easily just document.body as mentioned in the comments) to access the <body> tag.
It is often not needed to access the body tag directly within a Vue app. You can usually achieve the same thing in a Vueish way. In your case, you could just put a class onto to the highest element of your Vue app (the App.vue) and let this element act as your <body>. Then, you have full control over the template with Vue.
If you are using Vue 3 and you need to have a managed element outside of the highest element of your Vue app, you can also use the new <teleport> tag. This is e.g. used for modal overlays, but it won't help you to add a class to the body element. See the docs for <teleport>.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With