Skip to content

Conversation

@TheDoctor0
Copy link

This PR adds support for class-style component (written in TypeScript) used as persistent layout.

Class based VueComponent have different structure and component object is not available
on default level, as it it actually stored in nested options property.

Resubmitted from intertia-vue repository.

@AegirLeet
Copy link

This would be a great addition!

@claudiodekker claudiodekker changed the title [Vue] Add support for class based layout component. Add support for class based layout component. Oct 16, 2020
@claudiodekker claudiodekker added enhancement New feature or request vue 2 Related to the vue adapter labels Oct 16, 2020
@reinink
Copy link
Member

reinink commented Dec 28, 2020

Hey! I am looking to get some of these old PRs cleaned up. Is this PR still relevant? Can you update to resolve conflicts?

Also, I'm curious, is component.options a Vue class based component thing, or is this custom? I'm having a hard time merging this PR, because I know basically nothing about class based components...which is going to make this hard to maintain moving forward.

Do you have any workarounds that you're currently using to support this, that might be sufficient instead of updating this adapter?

@TheDoctor0
Copy link
Author

Hello @reinink,
I understand your hesitation about merging this PR and I'm not even surprised as this solution has been originally proposed more than a year ago.

A workaround that I use in my projects:

  1. layouts/Default.vue or layouts/Admin .vue
<template>
  // Template with slot for content
</template>

<script lang="ts">
import {Component, Vue} from 'vue-property-decorator';

@Component
export default class Default extends Vue {
  // Any custom logic for this layout.
}
</script>
  1. layouts/index.ts
import Default from './Default.vue';
import Admin from './Admin.vue';

export function DefaultLayout(h: any, page: any) {
  return h(Default, [page]);
}

export function AdminLayout(h: any, page: any) {
  return h(Admin, [page]);
}
  1. Page.vue
<script lang="ts">
import {DefaultLayout as Layout} from '@/layouts';
# or
import {AdminLayout as Layout} from '@/layouts';

export default class Page extends Vue {
  static layout = Layout;
}

This approach supports multiple layouts that can be defined in layouts/index.ts and later imported in page components.

@TheDoctor0
Copy link
Author

I just checked the docs and found this (added after this PR has been initially created):

// Using a render function
layout: (h, page) => h(Layout, [page]),

This is essentially the same thing as my workaround and works just fine:

import Default from "@/layouts/Default.vue";

export default class Page extends Vue {
  static layout = (h: any, page: any) => h(Default, [page]);
}

That pretty much makes this PR no longer relevant.
A simple comment in the documentation about using only this method in Vue class-based component should be more than enough.

@reinink
Copy link
Member

reinink commented Dec 28, 2020

Oh that's awesome! I suspect that means you could even use default layouts well.

A simple comment in the documentation about using only this method in Vue class-based component should be more than enough.

Submit a PR there? 🙏

@reinink reinink closed this Dec 28, 2020
@TheDoctor0
Copy link
Author

Oh that's awesome! I suspect that means you could even use default layouts well.

That's definitely possible, but I'll check it just to be sure.

Submit a PR there? 🙏

Of course 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request vue 2 Related to the vue adapter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants