[Vue] 8. Vue素子の再利用&汎用関数-1の開発)混入(Mixins)


かき混ぜる


Mixinsはvueプロジェクトで汎用関数を作成できる機能です.
前回はServer Dataでしたmockサーバ上のデータを呼び出して使用するコードをvueファイルに作成し、apiという関数を作成して使用しました.しかし、この関数はこの画面に必要なものではなく、ほとんどの画面でこの関数が使用されています.だから私はこの関数を共通の関数に変えて使いたいです.そんなとき、Mixinsを使ってみたいと思います.

mixinの使用

// ServerData.vue

async api(url, method, data) {
      return (
        await axios({
          method: method,
          url: url,
          data: data,
        }).catch((e) => {
          console.log(e);
        })
      ).data;
    },
main.jsと同じパスでapiを使用します.jsファイルを生成します.

次にapi関数を定義します.名前は$callapiに変更されます.関数名の前に$記号を付けるのは、この関数を構成部品で使用する場合、その名前が構成部品に存在する関数と重なる可能性があるためです.mixinはcallapiという関数をインポートして使用しますが、要素にcallapiという関数がある場合、関数が軽量化されすぎるという問題があります.したがって、名前の競合を防ぐためには、特殊な接頭辞を追加する必要があります.
// api.js
import axios from "axios";

export default {
  methods: {
    async $callAPI(url, method, data) {
      return (
        await axios({
          method: method,
          url: url,
          data: data,
        }).catch((e) => {
          console.log(e);
        })
      ).data;
    },
  },
};
MixinTestからviewsフォルダへ.vueファイルを作成します.
api.jsをインポートします.
import ApiMixin from "../api.js";
mixinにapiMixinを追加します.これでapijsで定義された関数コードは、その構成部品に直接コピーされます.
export default {
  mixins: [ApiMixin],
};
// MixinTest.vue
<template>
  <div>
    <button type="button" @click="getProductList">조회</button>
    <table>
      <thead>
        <tr>
          <th>제품명</th>
          <th>가격</th>
          <th>카테고리</th>
          <th>배송료</th>
        </tr>
      </thead>
      <tbody>
        <tr :key="i" v-for="(product, i) in productList">
          <td>{{ product.product_name }}</td>
          <td>{{ product.price }}</td>
          <td>{{ product.category }}</td>
          <td>{{ product.delivery_price }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
import ApiMixin from "../api.js";

export default {
  mixins: [ApiMixin],
  components: {},
  data() {
    return {
      productList: [],
    };
  },
  setup() {},
  created() {},
  mounted() {},
  unmounted() {},
  methods: {
    async getProductList() {
      this.productList = await this.$callAPI(
        "https://a1e284c5-db6b-4726-a0be-a72a59f81862.mock.pstmn.io/productList",
        "get",
        {}
      );
      console.log(this.productList);
    },
  },
};
</script>

<style scoped></style>
路線に登録する.
// index.js
const routes = [
  ...,
  {
    path: "/mixin",
    name: "MixinTest",
    component: () =>
      import(/* webpackChunkName: "about" */ "../views/MixinTest.vue"),
  },
];
ServeData.結果はvueで作成した結果と同じであることを確認できます.

mixin mountとcomponent mountの順序


mixin関数を定義するファイルにマウントする順序とcomponentにマウントする順序について説明します.
api.jsのマウントで、コンソールウィンドウに印刷コードを追加します.
// api.js
import axios from "axios";

export default {
  mounted() {
    console.log("믹스인 mounted");
  },
  methods: {
    async $callAPI(url, method, data) {
      return (
        await axios({
          method: method,
          url: url,
          data: data,
        }).catch((e) => {
          console.log(e);
        })
      ).data;
    },
  },
};
MixinTest.vueのマウントでは、コンソールウィンドウに印刷コードを追加することもできます.
// MixinTest.vue
export default {
  ..., // 이전 코드 생략
  mounted() {
    console.log("컴포넌트 mounted");
  },
};
mixinのマウントコードが最初に実行され、次にコンポーネントのマウントコードが表示されます.

mixinを使用してライフサイクルを使用する関数を作成する


vueライフサイクルは次のとおりです.要素上のユーザの滞留時間を測定する関数を作成しようとした.その後、mountedで時間を測定し、unmountedで時間を測定して減算することにより、ユーザが素子に滞在する時間を測定することができる.しかし、これらのコードを各コンポーネントに整理するのは不便です.だからmixinで作りたい

monitoring.jsファイルがメインです.jsと同じパスで作成および滞在する時間を計算するコードを作成したとします.
// monitoring.js
export default {
  mounted() {
      // 데이터베이스에 시간 저장
  },
  unmounted() {
      // 데이터베이스에 시간 저장
  },
};
MixinTest.vueファイルを監視します.jsをインポートしmixinに追加します.
// MixinTest.vue
<script>
import ApiMixin from "../api.js";
import MonitoringMixin from "../monitoring.js";

export default {
  mixins: [ApiMixin, MonitoringMixin],
};
</script>

mixinをグローバルと宣言


実際,$callapiのような関数はほとんどの素子で用いられる.しかし、すべての素子からこれを導入するたびに、実はとても面倒なことです.この場合、globalとして登録して使用することができます.
mixins.jsファイルがメインです.jsと同じパスに作成し、$callapi関数を同じ位置にコピーします.でも関数名は$apiと言いますね.
// mixins.js
import axios from "axios";

export default {
  methods: {
    async $api(url, method, data) {
      return (
        await axios({
          method: method,
          url: url,
          data: data,
        }).catch((e) => {
          console.log(e);
        })
      ).data;
    },
  },
};
main.mixinをjsにインポートし、使用設定を行います.
import mixins from "./mixins";
app.mixin(mixins);
// main.js
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import mixins from "./mixins";

const app = createApp(App);
app.use(router);
app.mixin(mixins);
app.mount("#app");
ではMixinTestvueからインポートする必要はありません.以前にimportとmixinにapiMixinを追加したコードをクリアし、再実行します.
// MixinTest.vue
<template>
  <div>
    <button type="button" @click="getProductList">조회</button>
    <table>
      <thead>
        <tr>
          <th>제품명</th>
          <th>가격</th>
          <th>카테고리</th>
          <th>배송료</th>
        </tr>
      </thead>
      <tbody>
        <tr :key="i" v-for="(product, i) in productList">
          <td>{{ product.product_name }}</td>
          <td>{{ product.price }}</td>
          <td>{{ product.category }}</td>
          <td>{{ product.delivery_price }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
// import ApiMixin from "../api.js";
import MonitoringMixin from "../monitoring.js";

export default {
  mixins: [MonitoringMixin],
  components: {},
  data() {
    return {
      productList: [],
    };
  },
  setup() {},
  created() {},
  mounted() {
    console.log("컴포넌트 mounted");
  },
  unmounted() {},
  methods: {
    async getProductList() {
      this.productList = await this.$api(
        "https://a1e284c5-db6b-4726-a0be-a72a59f81862.mock.pstmn.io/productList",
        "get",
        {}
      );
      console.log(this.productList);
    },
  },
};
</script>

<style scoped></style>
同様に、正常に動作していることを確認できます.

globalとしてmixinを使用する際の注意点


すべての余分な関数をglobalと宣言すると、これらの関数は構成部品でも実際には使用されませんが、関数コードはすべての構成部品にコピーされ、効率が低下します.したがって、ほとんどの構成部品で使用されている関数のみを宣言し、残りの部分は直接インポートして使用することをお勧めします.