ある中卒がWeb系エンジニアになるまでと、それからのこと

うつ病で高校を中退したり、たこ焼き屋のオヤジにホームページとたこ焼きを作らされたり、そのホームページが訴えられそうになったり、弁護士を目指したりした後にエンジニアになった人が書くブログ

vueファイルが肥大化しちゃうのを食い止めよう作戦その1

2020/07/14の日報

Hanasot開発の日報、第18日目です。
やったことは

  • vueのmethodsを外部ファイルに書き出してvueファイルを軽量化する

です。
時間は、

  • Hanasot開発 1h12min
  • 日報ブログ 40min

です。
運動は

  • エアロバイク 15min

です。

vueファイルが肥大化しちゃうのを食い止めよう作戦その1

今日は「vueファイルが肥大化しちゃうのを食い止めよう作戦」のpart1で、別ファイルに書き出せそうな処理は全部書き出してvueファイルを少しでも軽くしてみます。

今日別ファイルに移したのは下記の3つ。

    watch: {

      async isCameraOff(newValue) {
        const stream = this.localStream;
        stream.getVideoTracks()[0].enabled = !newValue;
        this.localStream = stream;
        await firebase.firestore().collection('rooms').doc(this.roomID).collection('participants')
          .doc(this.peer.id).update({'isCameraOff': newValue});
      },

      async isMuted(newValue) {
        const stream = this.localStream;
        stream.getAudioTracks()[0].enabled = !newValue;
        this.localStream = stream;
        await firebase.firestore().collection('rooms').doc(this.roomID).collection('participants')
          .doc(this.peer.id).update({'isMuted': newValue});
      },

    },
    methods: {

      timer(resolve, time) {
        this.time = time;
        const self = this;
        const interval = setInterval(function() {
          self.time--;
          if (!self.time) {
            clearInterval(interval);
            return resolve();
          }
        }, 1000);
      },

    },

watchプロパティの「isMuted」「isCameraOff」, methodsの「timer」ですね。

isMutedとisCameraOffは、dataプロパティの同名変数?フィールド?が変更された時に走ります。カメラ(あるいはマイク)の使用許可を切り替えるのと、dbを変更後の値で更新する感じです。そもそもこれwatchじゃなくても良かったなーと思って書き出しました。

次はtimerですが、これは普通のタイマーですね。time引数に取った数字で設定して、1秒ごとに引いていきます。で、0になったら止めると。単純ですのでこちらも書き出すのにピッタリ。

関数を別ファイルに書き出す

/src配下にapiディレクトリを作って、api.jsを作成します。名前は何でもいいし、なんならルートにapi.jsを置いたっていいんですが分かりやすいようにこうします。 で、api.jsの中身はこんな感じです。

import firebase from 'firebase';

export function timer (resolve, time, self) {
  self.time = time;
  const interval = setInterval(function () {
    self.time--;
    if (!self.time) {
      clearInterval(interval);
      return resolve();
    }
  }, 1000);
}

export async function offCamera(value, self) {
  self.isCameraOff = value;
  const stream = self.localStream;
  stream.getVideoTracks()[0].enabled = !value;
  self.localStream = stream;
  await firebase.firestore().collection('rooms').doc(self.roomID).collection('participants')
    .doc(self.peer.id).update({'isCameraOff': value});
}

export async function muteMic(value, self) {
  self.isMuted = value;
  const stream = self.localStream;
  stream.getAudioTracks()[0].enabled = !value;
  self.localStream = stream;
  await firebase.firestore().collection('rooms').doc(self.roomID).collection('participants')
    .doc(self.peer.id).update({'isMuted': value});
}

必要なライブラリをインポートしたあとにexport function 関数名 (){}とするだけです。

export 関数名() => {}とarrow関数で書いてもいいですが、シンプルにしました。

vueファイルで別ファイルの関数を読み込む

読み込み側は

import { timer, offCamera, muteMic } from '../api/api';

こうして、例えばtimerとかは

const self = this;
await new Promise(resolve => timer(resolve, 60, self));

こうします。

muteMicやoffCameraはtemplate内からも呼ぶ必要がありますが、importしたものを直接呼ぶことはできないのでcallMuteMic, callOffCameraを作成します。

    methods: {
      callOffCamera(value) {
        offCamera(value, this);
      },
      callMuteMic(value) {
        muteMic(value, this);
      },
    }

こんな感じですね。普通にmethodsとかで呼びたいなら

muteMic(true, this);

これだけです。

ちょっとハマったところ

thisの扱いです。3つすべてdataプロパティを更新する関数なので、thisをどうにかして渡す必要がありました。あんまりやらないほうがいいのかもですが、普通に引数にとってやると使えちゃったので今回はthisを引数で渡してます。

export function timer (resolve, time, self) {
  self.time = time;
  const interval = setInterval(function () {
    self.time--;
    if (!self.time) {
      clearInterval(interval);
      return resolve();
    }
  }, 1000);
}

selfという引数ですね。うっすら不安になるけどまあいいんじゃないでしょうか。

所感

前回の案件を参考にやりました。apiって呼んでるけどこれapiなのかな。広義のapiには含まれるんでしょうか。
あ、DBの更新処理なんかはfirebaseのcloud functionsを使うともっといい感じにできそうですね。ぼちぼちやろうかな。

関係ないんですが、仕事で最近shopifyを触ってます。liquidファイルは全然なじめないですけど、アプリ制作ではreactを使うんですよ。Reactやらなきゃなーと思ってたところだったので、仕事しながら勉強にもなって嬉しいです。