#はじめに
Vue.jsとTypeScriptで書こうとしたときに型の定義とかをどこに書いたらいいのか
わからずに書いたら結局Javascriptの書き方に逃げてしまい
その後調べてたらちょっとわかった気がしたので忘れないうちにメモ
そしてdisabledで苦戦。。。
##JavaScript + Vue
<script>
import firebase from "../plugins/firebase";
export default {
name: "images",
data() {
return {
storage: firebase.storage(),
db: firebase.firestore(),
auth: firebase.auth(),
image: "",
comment: "",
};
},
methods: {
selectImage(e) {
e.preventDefault();
this.image = e.target.files[0];
},
upLoad() {
const button = document.getElementById("postButton");
if (!this.image && !this.comment) {
alert("コメントを入力するか画像を選択してください");
return;
}
button.disabled = true;
const storageRef = this.storage.ref().child(`images/${this.image.name}`);
storageRef
.put(this.image)
.then(() => {
storageRef.getDownloadURL().then((url) => {
this.urlSave(url);
});
this.image = "";
this.comment = "";
button.disabled = false;
console.log("完了");
})
.catch(() => {
button.disabled = false;
alert("失敗しました");
});
},
urlSave(imageUrl) {
const user = this.auth.currentUser;
this.db
.collection("images")
.add({
uid: user.uid,
displayName: user.displayName,
comment: this.comment,
imageUrl: imageUrl,
timeStamp: firebase.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
console.log("db完了");
});
},
},
};
</script>
やっていることは、フォーム画面に入力されたテキスト、選んだファイルを
ファイルは__Storage__に保存して、ファイルの参照URL、テキスト、名前、日時を__FireStore__に保存
をしています。
そしてこの時は動いていた、、、
###これをTypeScriptで書いてみる。
##最初
<script lang="ts">
import firebase from "../plugins/firebase";
import { Component, Vue } from "vue-property-decorator";
export default class Images extends Vue {
storage = firebase.storage();
db = firebase.firestore();
auth = firebase.auth();
imageFile: any ;
comment: string | null;
selectImage(e: any) {
this.imageFile = e.target.files[0];
}
upLoad() {
const button = <HTMLInputElement>document.getElementById("postButton");//原因はここ
if (!this.imageFile && !this.comment) {
alert("コメントを入力するか画像を選択してください");//この部分でエラー
return;
}
button.disabled = true;
const storageRef = this.storage
.ref()
.child(`images/${this.imageFile.name}`);
storageRef
.put(this.imageFile)
.then(() => {
storageRef.getDownloadURL().then((url) => {
this.urlSave(url);
});
this.imageFile = "";
this.comment = "";
button.disabled = false;
console.log("完了");
})
.catch(() => {
button.disabled = false;
alert("失敗しました");
});
}
urlSave(imageUrl: string) {
const user = this.auth.currentUser;
if (user === null) {
return;
}
this.db
.collection("images")
.add({
uid: user.uid,
displayName: user.displayName,
comment: this.comment,
imageUrl: imageUrl,
timeStamp: firebase.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
console.log("db完了");
});
}
}
</script>
<template>
<div id="images">
<p>コメント</p>
<p>
<textarea v-model="comment" name id cols="30" rows="10"></textarea>
</p>
<p><input type="file" accept=”image/*” @change="selectImage" /></p>
<p>
<button id="postButton" @click="upLoad">投稿</button>
</p>
</div>
</template>
ここで問題発生、、、
コメントでいれてる箇所でエラーがでた
31:36 error Parsing error: '}' expected
31行目はalert()の部分だけど原因はわからず
そこで周辺のコードを消してみるとエラーは消えた
そこから徐々に絞っていくとどうやら
const button = <HTMLInputElement>document.getElementById("postButton");
この部分の__HTMLInputElement__としてるのが駄目らしい
けどこれを消して__disabled__を使ったらエラーがでる
そこで調べてたら__v-bind__でのやり方を見つけて
そっちで書き直してみたら、、、できた!
##修正後
<script lang="ts">
import firebase from "../plugins/firebase";
import { Component, Vue } from "vue-property-decorator";
@Component({})
export default class Images extends Vue {
storage = firebase.storage();
db = firebase.firestore();
auth = firebase.auth();
imageFile: any = "";
comment: string | null = "";
postButton = false;
selectImage(e: any) {
e.preventDefault();
console.log(e.target.files[0]);
this.imageFile = e.target.files[0];
}
upLoad() {
if (!this.imageFile && !this.comment) {
alert("コメントを入力するか画像を選択してください");
return;
}
this.postButton = true;
const storageRef = this.storage
.ref()
.child(`images/${this.imageFile.name}`);
storageRef
.put(this.imageFile)
.then(() => {
storageRef.getDownloadURL().then((url) => {
this.urlSave(url);
});
this.imageFile = "";
this.comment = "";
this.postButton = false;
console.log("完了");
})
.catch(() => {
this.postButton = false;
alert("失敗しました");
});
}
urlSave(imageUrl: string) {
const user = this.auth.currentUser;
if (user === null) {
return;
}
this.db
.collection("images")
.add({
uid: user.uid,
displayName: user.displayName,
comment: this.comment,
imageUrl: imageUrl,
timeStamp: firebase.firestore.FieldValue.serverTimestamp(),
})
.then(() => {
console.log("db完了");
});
}
}
</script>
一部__any__に逃げてしまいました。。。
<template>
<div id="images">
<p>コメント</p>
<p>
<textarea v-model="comment" name id cols="30" rows="10"></textarea>
</p>
<p><input type="file" accept=”image/*” @change="selectImage"/></p>
<p>
<button :disabled="postButton" @click="upLoad">投稿</button>
</p>
</div>
</template>
これで解決はできたけど結局なにがいけなかったのかよくわからずです。
最後までみて頂きありがとうございます。
間違いがあったらご指摘いただけると嬉しいです。
以上!