Skip to content

useElementAttrs | v-bind for elements outside the vue app #4958

@mrleblanc101

Description

@mrleblanc101

Clear and concise description of the problem

Hi 👋
I use Vue with Inertia, so the root template is rendered in PHP.
Here is the template:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <!-- Not reactive, comes from PHP -->
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title inertia>{{ config('app.name', 'Laravel') }}</title>

        @routes
        @vite(['resources/js/app.ts', "resources/js/pages/{$page['component']}.vue"])
        @inertiaHead
    </head>
    <body class="font-sans antialiased">
        @inertia
    </body>
</html>

Sometime, from the Vue app, I need to change some attributes on the <html> or <body> tag from the Vue.js.
For exemple, changing a theme class or attribute (data-theme), changing the lang attribute without doing a hard reload.

Currently, the best way would be to use a watch() and document.documentElement.dataset.theme = myRef, which is a bit ugly and verbose.

Suggested solution

It would be nice to have a VueUse composable for this.
Something like this:

useElementAttrs('html', {
    lang: i18n.locale
});

Another example:

useElementAttrs('body', {
    'data-theme': $page.props.theme
});

The first argument is a DOM selector, the second arguments are attrs to reactively sync with the element.
Maybe we could have a 3rd option argument with merging strategy (replace (default), concat/append) if the attrs already exist on the element.

To prevent misuse, maybe we should detect if the element is inside the Vue app, where we would show an error/warning so as to make to composable only usable with DOM nodes outside the Vue app.

Alternative

No response

Additional context

No response

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions