codememo

유형 스크립트와 함께 뷰에서 Mixins를 사용할 수 없습니다.

tipmemo 2023. 7. 13. 00:37
반응형

유형 스크립트와 함께 뷰에서 Mixins를 사용할 수 없습니다.

나는 이런 폴더 구조를 가지고 있습니다.

--Page    
   -group.vue    
--Services
  -groupMixin.ts

그룹 대본가치관

<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>

그룹 Mixin.ts의 코드

import { Vue } from 'vue-property-decorator'
//creating mixins.
export class GroupMixin extends Vue {
  test: string = 'sss'
}

저는 여기서 두 가지 문제에 직면해 있습니다.

먼저, 제가 사용한 ts 파일을 가져오기 위해 ../../, ./ 또는 @/를 사용할 수 있는 방법이 있습니까?lang="ts"를 사용하지 않고도 @/services/...와 같은 js 파일을 가져올 수 있습니다.

둘째, 그룹 mixin.ts에서 선언한 변수 테스트에 액세스할 수 없습니다.

저는 오늘 Vue mixins가 TypeScript 프로젝트에서 작동하도록 하는 방법을 생각하는 데 많은 시간을 보냈습니다.분명히 튜토리얼에서 믹스인을 사용하라고 하는 모든 일반적인 방법은 TypeScript에서 작동하지 않습니다.Vue 프레임워크의 mixin 코드가 TypeScript에 적합하지 않기 때문에 구성 요소는 mixin에 정의된 속성에 액세스할 수 없습니다.

결국, 저는 타입스크립트에서 믹스인을 작동시키는 방법을 찾았습니다.사실, 정말 잘 작동합니다.제 프로젝트에는 여러 수준의 혼합이 있습니다. 혼합은 다른 혼합을 확장합니다. 모든 것이 제가 예상했던 대로 정확히 작동합니다.비밀은 누군가가 TypeScript에서 믹스인을 수정하기 위해 작성한 이 타사 패키지를 설치해야 한다는 것이었습니다.

https://www.npmjs.com/package/vue-typed-mixins

몇 마디 경고합니다(그러나 둘 다 큰 문제는 아닙니다)

  1. 이 플러그인은 .vue 파일 대신 .ts 파일에 믹스인을 정의하는 경우에만 사용할 수 있습니다.내 믹스인에는 HTML이나 CSS가 없고 코드만 포함되어 있기 때문에 이것은 나에게 문제가 되지 않았습니다(그리고 나는 그것이 말이 되는 상황도 생각할 수 없습니다).

  2. 구성 요소에 믹스인을 포함할 때는 패키지 웹 사이트(위 URL)의 예제와 동일한 방법으로 혼합해야 합니다.사이트의 예제를 따르도록 코드를 리팩터링하지 않고 패키지를 설치하기만 하면 작동하지 않습니다.

다음은 간단한 예입니다.

// /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);
        }
    }
});

그러면 다음에서 사용됩니다.

// /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>

다음을 수행하여 혼합 작업을 수행하십시오.

그룹.값

<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>

그룹 Mixin.ts

import { Vue } from 'vue'

export class GroupMixin extends Vue {
  test: string = 'sss'
}

가 importing ▁importing다니있▁there▁using▁that▁reason습가▁is▁i져▁am▁a를 사용하는 이유가 있습니다.Vue용사를 import Vue from 'vue';▁like와 같은 Vue 기능을 하고 있기 입니다.$emit에서 한 경우vue-class-component.

합니다.vue-cli당신은 웹팩의 해결 별칭을 설정해야 할 것이고, 또한 당신의 에도 설정해야 할 이고, 가능하면 tsconfig-delays를 사용해야 할 것입니다.

@Joe Irby의 답변에 따르면, 저는 그것이 vue-type-mixins 없이 작동한다는 것을 발견했습니다.

Mixin이 Vue를 확장할 때 다음과 같이 Mixin을 확장하여 구성 요소를 생성할 수 있습니다.

// MyMixin.ts

import Vue from "vue";

export default Vue.extend({
    data: function () {
        return {
            message: "Message from MyMixin!"
        };
    }
});


// MyComponent.vue

<template>
    ...
</template>

<script lang="ts">
    import MyMixin from "@/mixins/MyMixin";

    export default MyMixin.extend({
        mounted: function () {
            console.log(this.message);
        }
    });
</script>

현재 유형 스크립트/값과 혼합하여 사용하는 방법은 두 가지가 있습니다.

  1. 혼합물에 변수만 포함되는 경우:
// 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
  }
}
  1. 라이프사이클 후크를 사용하는 경우:
// 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

이런 식으로 하면 저한테 효과가 있어요.'vue-class-component' 패키지를 확인할 수 있습니다. https://github.com/vuejs/vue-class-component/blob/master/test/test.ts#L389

믹스인츠

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;
}

파일 정보가치관

<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>

vue-class-component를 사용하지 않는 경우(현재는 설정/구성 api에서 잘 작동하지 않기 때문에 그렇지 않습니다), defineComponent를 mixin으로 사용할 수 있으며 vue 3의 typescript 작업입니다.

혼합물의 예:

yor_mixin.ts

import {defineComponent} from "vue"

interface MixinState{
    lastScrollPosition: number;
}

export default defineComponent({
    data(): MixinState{
        return {
            lastScrollPosition: 0,
        }
    },
    methods:{
        scrollDisable(){
            document.body.style.overflow = "hidden";
            this.lastScrollPosition = window.pageYOffset;
        },
        scrollEnable(){
            document.body.style.overflow = "auto";
            window.scrollTo(0, this.lastScrollPosition)
        }
    }
})

및 구성요소


<script lang="ts">
import {computed, defineComponent} from 'vue';
import {useStore, MUTATIONS} from "@/store";
import scrollDisableMixin from "@/mixins/scrollDisable";

export default defineComponent({
  mixins: [scrollDisableMixin],

  setup(){
    const store = useStore();
    return {
      expanded: computed(() => store.state.menu.expanded),
      toggle: () => store.commit(MUTATIONS.TOGGLE_MENU_MAIN),
    }
  },

  watch: {
    expanded: function(){
      this.expanded ? this.scrollDisable() :this.scrollEnable();
    }
  }

})

믹스인의 단점으로, https://codesandbox.io/s/delicate-sea-0xmim?file=/src/components/HelloWorld.vue:2262-2495 Comp의 설정에 믹스인의 리팩터를 만들어 보는 것은 어떨까요?가치관

export default {
  name: "HelloWorld",
  setup() {
    const { test } = useGroup();
    console.log(test);
    return Object.assign({}, useGroup());
  },
  mounted() {
    this.compRef = this;
  },
  props: {
    msg: String,
  },
};

Group.js 사용

import { ref, nextTick, onMounted } from "vue";

export default () => {
  const compRef = ref(null);
  const test = "Hello World!";

  onMounted(() => {
    nextTick(() => {
      if (compRef.value) {
        const vm = compRef.value;
        console.log(vm.$el, vm.msg);
      }
    });
  });
  return {
    test,
    compRef
  };
};

이 대답은 vue-class-component(데코레이터)를 기꺼이 사용하는 사람들을 위한 것입니다.당신이 해야 할 일은 'vue-class-component'에서 Options를 가져와서 거기에 믹스를 추가하는 것입니다.

단계:

1 - 믹스인 만들기:이 예에서는 시간 형식을 지정하기 위해 믹스인을 작성하고 있습니다(HH:MM:ss)

//Mixin
 export default {
   methods: {
     formatTime(date: string) {
       return new Date(date)
         .toTimeString()
         .replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
     },
   },
 };

2 - 구성요소에 믹스인을 옵션 데코레이터에 추가하여 사용합니다.

   //Home.vue

    import { Options, Vue } from "vue-class-component";

    import formatTimeMixin from '../mixin/formatTime';

    <template>
       <h1> Time left: {{formatTime(timeLeft)}} </h1>
    </template>

    @Options({
      mixins: [formatTimeMixin],
    })
    export default class Home extends Vue {
       timeLeft = 10000;
    }

바로 그거야, 이것이 누군가에게 도움이 되기를!

더 이상 "믹스인"이라고 생각하지는 않겠지만, 효과가 있습니다.

도우미 믹스 정렬

import Vue from "vue";
export default Vue.extend({
  methods: {
    sortDate(a: string, b: string): number {
       ...
    },
  }
})

내 구성요소.가치관

import SortHelperMixin from '@/mixins/SortHelperMixin'
export default Vue.extend({
  name: "MyComponent",
  data() {
    return {
      sortHelperMixin: new SortHelperMixin(),
    };
  },
})

사용하다

this.sortHelperMixin.sortDate(a, b)

언급URL : https://stackoverflow.com/questions/51873087/unable-to-use-mixins-in-vue-with-typescript

반응형