Open rudnik275 opened 3 years ago
As a note: I'm unsure of the feasibility of this one but if someone figures out how to type it, please file a PR!
For the time being using vue-class-component can help here. For instance with having a class-style Vue component named "Main" you can just do the following:
next(vm => {
const main = vm as Main;
main.customVariable = 'changed text';
});
It still feels like a hack but it works at least.
I met same problem today,and I solved problem. actually,according to my console log,vm has property customVariable. so this problem same like caused by typescript type.
vm.customVariable = 'changed text'
change to:
(vm as any).customVariable = 'changed text'
It worked for me.
there is my code.
import {defineComponent} from 'vue';
import baseurl from "@/api/baseurl";
const axios = require('axios').default;
export default defineComponent({
name: 'ProductPage',
data() {
const product = {
id: 0,
name: '',
type: '',
description: '',
saleUserid: -1,
salePrice: 0,
picUrl: ''
}
return {
product,
};
},
props: ['id'],
beforeRouteEnter(to, from, next) {
axios.get(baseurl.getProducts + '/' + to.params.id)
.then((response: any) => {
next(vm => {
// console.log(vm)
// console.log((vm as any).product)
(vm as any).product = response.data;
})
console.log(response);
})
.catch(function (error: any) {
console.log("GET PRODUCT ERROR!!!")
console.log(error);
});
}
});
Another option would be to assign the component to a variable and then use vm as InstanceType<typeof Component>
e.g.:
import axios from "axios";
import {defineComponent} from "vue";
const Component = defineComponent({
async beforeRouteEnter(to, from, next) {
const data = (await axios.get("/products/" + to.params.id)).data;
next(vm => {
(vm as InstanceType<typeof Component>).product = data;
});
},
data() {
return {
product: {},
};
}
});
export default Component;
You can import the module from itself:
<script lang="ts" setup>
// in MyComp.vue
import type Self from './MyComp.vue'
const foo = 'bar'
defineExpose({
foo,
})
defineOptions({
beforeRouteEnter: (to, from, next) => {
next(async (vm: InstanceType<typeof Self>) => {
vm.foo // string
})
},
})
</script>
@posva NavigationGuard
is missing a generic to be able to pass the type of vm
in next
@posva Also the typing seems to be off as the type of the current component is not compatible with the signatures of next
:
I don't know where InstanceType
comes from. It doesn't come from vue-router but I imagine it should be assignable to ComponentPublicInstance
in order for it to work.
NavigationGuard
doesn't really need a generic as long as you can specify a more concrete type of component instance. BTW beforeRouteEnter
is of type NavigationGuardWithThis
, not NavigationGuard
BTW beforeRouteEnter is of type NavigationGuardWithThis
You are sure? I though there is no this
in beforeRouteEnter
Yes, because it has the this
explicitly set to undefined
😅
Version
4.0.2
Reproduction link
https://codesandbox.io/s/competent-architecture-4ezib?file=/src/App.vue
Steps to reproduce
What is expected?
returns correct instance variables
What is actually happening?
Property 'customVariable' does not exist on type 'ComponentPublicInstance{}, {}, {}, {}, {}, {}, {}, {}, false, ComponentOptionsBase >'.