Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 🐛 Support reactive useMeta in layouts #65

Closed
wants to merge 1 commit into from

Conversation

miii
Copy link
Contributor

@miii miii commented May 18, 2020

This PR uses Vue.observable instead of reactive to create meta refs to enable usage of useMeta() in layouts. This will also refresh vue-meta automatically if the state is updated. Since the observable API is used, Vue 2.6.0+ is required. Let me know if there are any issues with the suggested change.

Closes: #64

Set or update head metadata anytime in your setup method

✅ Closes: nuxt-community#64
@vercel
Copy link

vercel bot commented May 18, 2020

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/nuxt-community/composition-api/pa5oij2qi
✅ Preview: https://composition-api-git-fork-miii-master.nuxt-community.now.sh

@danielroe
Copy link
Member

@miii I really appreciate this PR and the associated issue. I think the issue is bigger than just useMeta, however - as nothing Composition API-related could be used in layouts either. If we just solve the useMeta issue, the bigger problem remains. So I'm deploying a fix. Do let me know if it doesn't fix the error, however, or if you think there's still a need to use Vue.observable instead (which is what reactive uses under the hood).

@danielroe danielroe closed this May 19, 2020
@miii
Copy link
Contributor Author

miii commented May 20, 2020

@danielroe great solution, thanks! Seems to be working properly for me.
I still have issues with the reactive integration with vue-meta.

For example:

setup (_, { root }) {
    const { title } = useMeta({ title: 'Init' });
    const { route } = useContext();

    watch([title], () => {
        // This watcher will never be triggered
        console.log('Title updated:', title);
    });

    watchEffect(() => {
      title.value = route.value.path;
      root.$meta().refresh(); // <-- this is required to refresh vue-meta
    });
}

In my opinion useMeta() should be reactive without having to call $meta().refresh() manually, like head() behaves. I think the watch issue is caused by the use of Object.assign().
https://vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

Object.assign(_head, options.head)

Object.assign(_head, createEmptyMeta())
Object.assign(_head, init || {})

I attempted to address this issue in the PR with Vue.set(), although it may not be perfect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

fix: useMeta() throws error if used in a layout
2 participants