こんにちわgakuです。
最近、また、vue+firebase欲が出てきてしこしこ勉強している今日この頃でございます。
さて、久しぶりにvue-cliをupdateすると、「TypeScript」周りがかなり強化されていることに気づきました。
今まで、「TypeScript+vueは人類には早すぎる」と思っておりましたが、そろそろ言い訳もできない感じになってきましたので、こちらも習得中でございます。
そんな中、Vue+TypeScriptを触っていると、独自プラグインの実装で結構ハマった点があったので、今回はそんな話を記載しようかと思います。
動かない独自プラグイン
firebaseをvueに組み込む際、component内で触りやすくするために独自プラグインを実装し使用するとちょっとだけ楽になります。
具体的には以下のように記述することで、どのcomponentでも「this.$auth.・・・」、「this.$firestore.・・・」みたいな形でアクセスすることができ、importを毎度行わなくてよくなります。
import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/auth';
import config from './config';
export default {
install(Vue: any, options: any) {
const firebaseApp = firebase.initializeApp(config);
// instance propertyの登録
Vue.prototype.$firestore = firebaseApp.firestore();
Vue.prototype.$auth = firebaseApp.auth();
},
};
export default{
apiKey: '***',
authDomain: '***',
databaseURL: '***',
projectId: '***',
storageBucket: '***',
messagingSenderId: '***',
};
で、こんな感じで実装したら、main.tsで以下を追記することで、vue+jsの時はすんなり動きました。
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import './registerServiceWorker';
import firebase from './firebase'; // 追記
Vue.use(firebase); //追記
Vue.config.productionTip = false;
new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app');
が、TypeScriptだとErrorが出て死にます。(カナシミ(´・ω・`)
ERROR in /Users/gaku/src/bitbucket.org/gakussolution/esetwitter/app/src/views/Signup.vue
23:10 Property '$auth' does not exist on type 'Signup'.
21 |
22 | public signUp() {
> 23 | this.$auth.createUserWithEmailAndPassword(this.username, this.password)
| ^
24 | .then((data: firebase.auth.UserCredential) => {
25 | if (data.user !== null) {
26 | this.$router.push({name: 'home'});
ERROR in /Users/gaku/src/bitbucket.org/gakussolution/esetwitter/app/src/views/Signup.vue
34:10 Property '$firestore' does not exist on type 'Signup'.
32 | }
33 | public insert() {
> 34 | this.$firestore.collection('test').add({
| ^
35 | name: 'test',
36 | disp: 'testtest',
37 | });
対処法
TypeScriptの場合、こういったプラグインの実装には新たに型定義情報を追加してあげる必要があるみたいです。
なので、型定義を以下のように記述し配置してあげます。
import Vue from 'vue'
import firebase from 'firebase/app'
declare module 'vue/types/vue' {
interface Vue {
$auth: firebase.auth.Auth,
$firestore: firebase.firestore.Firestore
}
}
これで先程出力されたerrorがなくなり、めでたくcomponent内で「this.$auth.・・・」でアクセスできるようになります(´・ω・`)b
おわりに
vue+TypeScriptはかなり人類に優しくなりましたね。
vue-cli3.6だと、component内で「vue-property-decorator」を呼び出すテンプレートが記述されており、かなり迷いなく実装することができるようになったのではないかという印象です。
(2018年の終わり頃の段階では、このライブラリはテンプレート内に記述されておらず、実装者が選定するものであったと記憶しています。
また、最近、エディタをvimからVSCodeに最近変更しました。
VSCodeだと、設定ほぼ無しで補完がばっちばちに効いてくれるのでTypeScriptは良い感じだなと思っております。