问题
I have a folder structure like this
--Page
-group.vue
--Services
-groupMixin.ts
script of group.vue
<script lang="ts">
import { Vue, Component, Mixins } from 'vue-property-decorator'
import { GroupMixin } from '../../services/groupMixin';
@Component
export default class Group extends Mixins(GroupMixin) {
created () {
console.log(this.test)
}
}
</script>
code of groupMixin.ts
import { Vue } from 'vue-property-decorator'
//creating mixins.
export class GroupMixin extends Vue {
test: string = 'sss'
}
I am facing two problems here.
First, to import a ts file i used ../../, is there any way to use ./ or @/. Without using lang="ts", i can import a js file like this @/services/...
Second, not able to access the varaible test which i declared in groupmixin.ts.
回答1:
Please try to do the following to make your mixin to work:
group.vue
<script lang="ts">
import Vue from 'vue';
// mixins only exist in `vue-class-component` and Component is a default export.
import Component, { mixins } from 'vue-class-component';
import { GroupMixin } from '../Services/groupMixin';
@Component
export default class Group extends mixins(GroupMixin) {
created () {
console.log(this.test)
}
}
</script>
groupMixin.ts
import { Vue } from 'vue'
export class GroupMixin extends Vue {
test: string = 'sss'
}
There is a reason that I am using importing Vue
using import Vue from 'vue';
, it is mainly because some IDE's are highlighting Vue functions like $emit
when it is imported from vue-class-component
.
As for import ts files if you are not using vue-cli
you'll need to setup webpack's resolve alias and also in your tsconfig.json and possibly will need to use tsconfig-paths
回答2:
I spent a lot of time today trying to figure out how to get Vue mixins to work in a TypeScript project. Apparently all the normal ways that the tutorials say to use mixins simply do not work in TypeScript. The components don't have access to the properties defined in their mixins because apparently the Vue framework's mixin code just isn't TypeScript-friendly.
Eventually, I did find a way to get mixins working in TypeScript. Working really well, in fact. I have multiple levels of mixin inheritance in my project, with mixins extending other mixins, and it all works exactly how I expected it to. The secret was that I had to install this third-party package that someone wrote to fix mixins in TypeScript:
https://www.npmjs.com/package/vue-typed-mixins
Couple words of warning (but neither is a big deal):
This plugin only works for me if I define my mixins in .ts files instead of .vue files. This wasn't a problem for me because my mixins only contain code, no html or css (and I can't think of a situation where that would even make sense).
When you include a mixin on a component, make sure you do it the same way as the example on the package's website (url above). If you simply install the package without refactoring your code to follow the example on the site, it won't work.
Here's a simple example:
// /src/mixins/MyMixin.ts
import Vue from "vue";
export default Vue.extend({
data: function () {
return {
mixinMessage: "this came from MyMixin!"
};
},
created: function () {
console.log("MyMixin.created()");
},
mounted: function () {
console.log("MyMixin.mounted()");
},
methods: {
mixinOutput: function (text:string) {
console.log("mixin says: " + text);
}
}
});
Which is then used by:
// /src/components/MyComponent.vue
<template>
<div>
whatever
</div>
</template>
<style>
/* whatever */
</style>
<script lang="ts">
import mixins from "vue-typed-mixins";
import MyMixin from "../mixins/MyMixin";
export default mixins(MyMixin).extend({
created: function () {
console.log("MyComponent.created()");
},
mounted: function () {
console.log("MyComponent.mounted()");
this.mixinOutput("hello from MyComponent");
this.mixinOutput(this.mixinMessage);
}
});
</script>
回答3:
As of today there's 2 ways to use a mixin with Typescript/Vue:
- If your mixin holds just variables:
// mixins/title.ts
import { Vue, Component } from 'vue-property-decorator'
@Component
export default class titleMixin extends Vue {
public test: string = 'Hello, hello, hello'
}
// Page.vue
import { Component, Vue, Mixins } from 'vue-property-decorator'
import titleMixin from '@/mixins/title'
export default class Page extends Mixins(titleMixin) {
private mounted(): void {
console.log(this.test) // would print: Hello, hello, hello
}
}
- If you're using lifecycle hooks:
// mixins/title.ts
import { Vue, Component } from 'vue-property-decorator'
@Component
export default class titleMixin extends Vue {
private mounted(): void {
console.log('somevalue')
}
}
// Page.vue
import { Component, Vue } from 'vue-property-decorator'
import titleMixin from '@/mixins/title'
@Component({
mixins: [titleMixin]
})
export default class Page extends Vue {} // this will print console.log
This way it works for me. You can take a look at 'vue-class-component' package: https://github.com/vuejs/vue-class-component/blob/master/test/test.ts#L389
回答4:
mixins.ts
import { Vue, Component } from "vue-property-decorator";
@Component
export default class Mixin extends Vue {
public perfectScrollbarSetting: object = {
maxScrollbarLength: 750
};
public widthClient: number = 0;
public heightClient: number = 0;
}
file About.vue
<template>
</template>
<script lang="ts">
import { Vue, Component, Mixins } from "vue-property-decorator";
import { generalInfo } from "../../store/modules/general";
import Mixin from "../../mixin/mixins";
@Component({
mixins: [Mixin]
})
export default class About extends Mixins(Mixin) {
mounted() {
console.log(this.widthClient) //it's work
}
}
</script>
来源:https://stackoverflow.com/questions/51873087/unable-to-use-mixins-in-vue-with-typescript