https://github.com/envision/nuxt-middleware-ts-class-bug
npx create-nuxt-app nuxt-middleware-ts-class-bug
? Project name nuxt-middleware-ts-class-bug
? Project description Reproducing Nuxt bug with middleware not applied to class style page component
? Use a custom server framework none
? Choose features to install (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Use a custom UI framework none
? Use a custom test framework none
? Choose rendering mode Universal
? Author name Janne Kurkinen
? Choose a package manager yarn
cd nuxt-middleware-ts-class-bug
Add a new file middleware/vanilla.js
:
export default function() {
console.log('Middleware: testing vanilla')
}
In pages/index.vue
, apply middleware so that the single file component's script section looks like this:
<script>
import Logo from '~/components/Logo.vue'
export default {
components: {
Logo
},
middleware: ['vanilla']
}
</script>
Run yarn dev
Open the browser and verify that 'Middleware: testing vanilla' has been logged to console after visiting the page.
Good, middleware working in JS. Then lets change to TypeScript...
Add a new file under project root tsconfig.json
:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"lib": [
"esnext",
"esnext.asynciterable",
"dom"
],
"esModuleInterop": true,
"experimentalDecorators": true,
"allowJs": true,
"sourceMap": true,
"strict": true,
"noImplicitAny": false,
"noEmit": true,
"baseUrl": ".",
"paths": {
"~/*": [
"./*"
],
"@/*": [
"./*"
]
},
"types": [
"@types/node",
"@nuxt/vue-app"
]
}
}
Run yarn add -D @nuxt/typescript nuxt-property-decorator
Add a new file middleware/typescript.ts
:
export default context => {
console.log('Middleware: typescript testing');
};
In pages/index.vue
change the middleware name from 'vanilla' to 'typescript'.
Run yarn dev
and verify again that 'Middleware: typescript testing' is logged after visiting the page.
Now change `pages/index.vue麓 script section to implement an exported class component:
<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator';
import Logo from '~/components/Logo.vue';
@Component({
components: {
Logo
}
})
class Index extends Vue {
middleware = ['typescript'];
}
export default Index;
</script>
Run in the browser and verify that no middleware gets logged...
Class style page components should have middleware applied.
MIddleware gets applied to pages with object style export, but not with class style export extending Vue.
I think this is what you want:
<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator';
import Logo from '~/components/Logo.vue';
@Component({
components: {
Logo
},
middleware: ['typescript']
})
class Index extends Vue {}
export default Index;
</script>
By adding middleware
in the class you are creating a data property, which is why it appears not to work.
Thanks for the tip @danielroe, your solution is working!
Docs upgrade should be warranted regarding this...
@envision Feel free to send in a PR!
@manniL, I could make a PR but in this case I do not understand why the middleware property needs to be defined in the Component decorator, and why is it not working when defined in the actual component class?
cc @kevinmarrec
@envision declaring it in Component
is IMO more logical if you take some of these following considerations :
Only nuxt-property-decorator
allows to define it in classes (it uses something called Vue Component Hook registration) but I'm not a fan of this apparoach as it can brings undesirable issues like your case where middleware
is handled by TypeScript as a data property and not as a Component option
.
middleware
, asyncData
and all others Page API methods that integrates Nuxt are Component options, and that's why it should IMO stays in Component section as standard way, but you can use nuxt-property-decorator
if you like the way to define things in the class. But IMO it's easier to read code when keeping Nuxt logic in Component section and your own logic in the class.
Nuxt TypeScript documentation is using vue-property-decorator
and is declaring asyncData
in Component options so docs don't need upgrade for now.
If stick with nuxt-property-decorator
and have issues, please open a new issue on the respective repository :)
/cc @husayt
Most helpful comment
I think this is what you want:
By adding
middleware
in the class you are creating a data property, which is why it appears not to work.