20210512のvue.jsに関する記事は10件です。

npm run dev を行ったときの、newline required at end of file but not found のエラーの対処

vue.jsとrouterを読み込んだプログラムを再び npm run dev でビルドしたときのエラーの対処をまとめます。 エラーコードをみると newline required at end of file but not found src\router\index.js:20:3 ファイルの最後に空白が必要ということが書いてあります。 上記のコードのもと src\router\index.js の最後の行が詰まっていたので、改行します。 import Vue from 'vue' import Router from 'vue-router' import page1 from '@/components/page1' import page2 from '@/components/page2' Vue.use(Router) export default new Router({ routes: [ { path: '/', component: page1 }, { path: '/page2', component: page2 } ] })  ここが改行してできた行 これをしたら正常にビルドできました。 また、 npm run dev のビルドを実行するときは、 vue create でつくったファイルに移動してから実行しないと動きません。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue】CompositionAPIでcomputed, data, method

data Vue2で定義していたdataプロパティ内の変数はcompositionAPIからはreactive又はrefの中に定義する <script lang="ts"> import { defineComponent } from 'vue' export default defineComponent({ setup() { const state = reactive({ hoge: 'huga' }) return { state } } }) </script> 型定義する場合 <script lang="ts"> import { defineComponent } from 'vue' export default defineComponent({ setup() { const state = reactive<string>({ hoge: 'huga' }) return { state } } }) </script> computed Vue2ではcomputedプロパティ内で記述していたメソッドはCompositionAPIではかなり異なる <template> <div>{{fullName}}</div> </template> <script lang="ts"> import { defineComponent, computed } from 'vue' interface UserName { firstName: string lastName: string } export default defineComponent({ setup() { const state = reactive<UserName>({ firstName: 'hoge', lastName: 'huga' }) const fullName = computed(():string => state.firstName + state.lastName) return { state, fullName } } }) </script> method Vue2ではmethodプロパティ内でメソッド定義していたがCompositionAPIでは異なる <template> <div> <button @click="clickEvent()">Click Me!<button> </div> </template> <script lang="ts"> import { defineComponent } from 'vue' export default defineComponent({ setup() { const clickEvent = ():void => alert('Clickしたよ!') return { clickEvent } } }) </script> 関数型でかけていい感じ! Vue+TypeScriptの公式
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

vue.jsとVue Routerを用いて、簡易なwebアプリ(SPA)を作る CDN読み込み

環境 windows10 Vue routet を CDNを用いて行います。 index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Vue Router</title> <!-- Vue Router のCDNの読み込み --> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> </head> <body> <div id="app"> <h1>{{ title }}</h1> <nav> <router-link to="/">ホーム</router-link> <router-link to="/news">ニュース</router-link> <router-link to="/about">About</router-link> </nav> <router-view/> </div> <!-- javascriptの記述 --> <script> // コンポーネントの設定 const Home = { template: '<div>初めてのVue Resource</div>'} const News = { template: '<div>今週のニュースは....</div>'} const About = { template: '<div>会社までのアクセス方法は....</div>'} // ルーティングの設定 const router = new VueRouter({ routes : [ {path:'/', component : Home}, {path:'/news',component: News}, {path:'/about',component: About} ] }) //Vueインスタンスへrouterインスタンスを渡す var app = new Vue({ el: '#app', data:{ title: 'Vue Resource', }, router, }); </script> </body> </html> とりあえず動かしたい人はコピペしてください。 なぜか公式のURLコピペしても動かなかったので参考までに。 参考 https://reffect.co.jp/vue/first-time-vue-router 細かい解説は https://qiita.com/yuta-38/items/889f5edc5a0075aba274
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue.js】$emitメソッドの正体 コンポーネント(子→親)の間のデータ受け渡しでやってる事

はじめに 仕事で使う事になったので1からVue.jsについて学んだ。 ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。 $emitメソッドの正体 コンポーネント(子→親)の間のデータ受け渡しでやってる事 カスタムイベントを定義・発火させることができるメソッド1。 このメソッドを応用して、コンポーネント間(子→親)のデータの受け渡しを行う事ができる。 動画のソースコードは以下2。 parent-component.vue <template> <div> <LikeHeader></LikeHeader> <h2>{{ number }}</h2> <LikeNumber :total-number="number" @my-click="number = $event"></LikeNumber> </div> </template> <script> import LikeHeader from "./components/LikeHeader.vue"; export default { data() { return { number: 10, }; }, components: { LikeHeader, } }; </script> <style scoped> div { border: 1px solid blue; } </style> child-component.vue <template> <div> <p>いいね({{ halfNumber }})</p> <button @click="increment">+1</button> </div> </template> <script> export default { props: ["totalNumber"], computed: { halfNumber() { return this.totalNumber / 2; }, }, methods: { increment() { this.$emit("my-click", this.totalNumber + 1); }, }, }; </script> <style scoped> div { border: 1px solid red; } </style> ここでは、child-component.vue(子)からparent-component.vue(親)へデータの受け渡しを行っている。 上記の考え方としては、 child-component.vueの方で$emitメソッドでカスタムイベントmy-clickを定義し発火させる その際に$emitメソッドでは第二引数を取る事ができるので、第二引数に値this.totalNumber + 1を渡すようにする parent-component.vueでは、v-onディレクティブでカスタムイベントmy-clickが発火した際に何らかの処理を行うように設定する事を考える v-onディレクティブの@hoge=""の""はJavaScriptを書く事ができるのでそこでparent-component.vueのdataプロパティの値を$eventの値に変更するようにする というもの。$emitメソッドでカスタムイベントを発火させた場合、$eventには$emitメソッドの第二引数3の値が渡る仕様になっているので、上記のような考え方で実装する事で、$emitメソッドを応用して「子→親のコンポーネント間データ渡し」が実現できる。 ※補足 $emitメソッドでは第二引数は任意の引数で省略可能4。 つまり、$emitメソッドは純粋にカスタムイベントを定義・発火させるためのメソッドであり、オプションとして第二引数にデータを設定するとイベント発火時に$eventにデータを渡す事ができるというだけ。 子→親のデータの受け渡しは$emitメソッドのカスタムイベント発火機能に便乗して実現されている。 @my-click="number = $event"の書き換え @my-click="number = $event"は以下のような実装に書き換える事もできる。 sample.vue <template> <!-- ・・・ --> <LikeNumber :total-number="number" @my-click="increaseNumber"></LikeNumber> <!-- ・・・ --> </template> <script> // ・・・ }, methods: { increaseNumber(value) { this.number = value; }, }, // ・・・ </script> ※v-onディレクティブのJavaScriptの部分がmethodsプロパティで定義された関数でかつその引数が$eventしかない場合は省略可能なので、上記の実装では@my-click="increaseNumber"と書いている。 propsのように簡単でないのはなぜ? propsを用いると、親→子のコンポーネント間データ渡しが簡単にできるが、その逆(子→親)はなぜ$emitメソッドを使うなど面倒な事をしなければ実現できないのか?という事を思うだろう。 これはVue.jsが、単一方向のデータ渡ししかできないようにする事で、データフローを親→子へのみに限定し、データフローの複雑化を防止してシンプルになるようにしているため。 つまり、Vue.jsのコンポーネントでは、 子は親(のdata)に依存する 親は子(のdata、props)に依存しない という設計がなされている。 ※ちなみに、子コンポーネントで親から渡ってきたデータを変更すると Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "totalNumber"(親コンポーネントが再レンダリングされるたびに値が上書きされるため、プロップを直接変更することは避けてください。 代わりに、小道具の値に基づいてデータまたは計算されたプロパティを使用してください。 変更されるプロップ: "totalNumber") というエラーが出る。 Vue.jsでは親→子のコンポーネント間データ受け渡しをする(子が親に依存する)場合、子側で親から渡ってくるデータを変更しないようにオススメしている。 propsでオブジェクト・配列を渡す時は参照渡しになるのでより注意する オブジェクト・配列を変数に格納すると参照渡しになるように、Vue.jsでも親→子でコンポーネント間データ渡しでオブジェクト・配列をpropsで渡すと参照渡しになってしまう。 この場合、子コンポーネントでpropsで渡ってきた値を書き換えた時、親のdataの値も書き換えられるという影響が出るので注意が必要。 ※基本的には上記で述べたように、子側で親から渡ってくるデータを変更しないが原則なので、予期せぬバグを発生させないためにも子側で親から渡ってきたpropsを変更しないようにする。 $emitメソッドのカスタムイベント名はケバブケースで カスタムイベントはHTML上5に書く事になるので、基本的にはHTML側の慣例にならいケバブケースで書くのがオススメ。 Vue.jsの勉強メモ一覧記事へのリンク Vue.jsについて勉強した際に書いた勉強メモ記事のリンクを集約した記事。 https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4 Vueインスタンスに標準で定義されているもの ↩ ソースコード全体を見たい場合はここ ↩ interfaceを見ると$emit(event: string, ...args: any[]): this;となっている第二引数は...args: any[]で、これはarrayだが1つの要素しかない場合はその値が$eventに渡される ↩ 上記の例で言えば、単にthis.$emit("my-click");と書く事もできるという事 ↩ 正確にはsingle file componentのtemplate ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue.js 勉強メモ】$emitメソッドの正体 コンポーネント(子→親)の間のデータ受け渡し

はじめに 仕事で使う事になったので1からVue.jsについて学んだ。 ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。 $emitメソッドの正体 カスタムイベントを定義・発火させることができるメソッド1。 このメソッドを応用して、コンポーネント間(子→親)のデータの受け渡しを行う事ができる。 動画のソースコードは以下2。 parent-component.vue <template> <div> <LikeHeader></LikeHeader> <h2>{{ number }}</h2> <LikeNumber :total-number="number" @my-click="number = $event"></LikeNumber> </div> </template> <script> import LikeHeader from "./components/LikeHeader.vue"; export default { data() { return { number: 10, }; }, components: { LikeHeader, } }; </script> <style scoped> div { border: 1px solid blue; } </style> child-component.vue <template> <div> <p>いいね({{ halfNumber }})</p> <button @click="increment">+1</button> </div> </template> <script> export default { props: ["totalNumber"], computed: { halfNumber() { return this.totalNumber / 2; }, }, methods: { increment() { this.$emit("my-click", this.totalNumber + 1); }, }, }; </script> <style scoped> div { border: 1px solid red; } </style> ここでは、child-component.vue(子)からparent-component.vue(親)へデータの受け渡しを行っている。 上記の考え方としては、 child-component.vueの方で$emitメソッドでカスタムイベントmy-clickを定義し発火させる その際に$emitメソッドでは第二引数を取る事ができるので、第二引数に値this.totalNumber + 1を渡すようにする parent-component.vueでは、v-onディレクティブでカスタムイベントmy-clickが発火した際に何らかの処理を行うように設定する事を考える v-onディレクティブの@hoge=""の""はJavaScriptを書く事ができるのでそこでparent-component.vueのdataプロパティの値を$eventの値に変更するようにする というもの。$emitメソッドでカスタムイベントを発火させた場合、$eventには$emitメソッドの第二引数3の値が渡る仕様になっているので、上記のような考え方で実装する事で、$emitメソッドを応用して「子→親のコンポーネント間データ渡し」が実現できる。 ※補足 $emitメソッドでは第二引数は任意の引数で省略可能4。 つまり、$emitメソッドは純粋にカスタムイベントを定義・発火させるためのメソッドであり、オプションとして第二引数にデータを設定するとイベント発火時に$eventにデータを渡す事ができるというだけ。 子→親のデータの受け渡しは$emitメソッドのカスタムイベント発火機能に便乗して実現されている。 @my-click="number = $event"の書き換え @my-click="number = $event"は以下のような実装に書き換える事もできる。 sample.vue <template> <!-- ・・・ --> <LikeNumber :total-number="number" @my-click="increaseNumber"></LikeNumber> <!-- ・・・ --> </template> <script> // ・・・ }, methods: { increaseNumber(value) { this.number = value; }, }, // ・・・ </script> ※v-onディレクティブのJavaScriptの部分がmethodsプロパティで定義された関数でかつその引数が$eventしかない場合は省略可能なので、上記の実装では@my-click="increaseNumber"と書いている。 propsのように簡単でないのはなぜ? propsを用いると、親→子のコンポーネント間データ渡しが簡単にできるが、その逆(子→親)はなぜ$emitメソッドを使うなど面倒な事をしなければ実現できないのか?という事を思うだろう。 これはVue.jsが、単一方向のデータ渡ししかできないようにする事で、データフローを親→子へのみに限定し、データフローの複雑化を防止してシンプルになるようにしているため。 つまり、Vue.jsのコンポーネントでは、 子は親(のdata)に依存する 親は子(のdata、props)に依存しない という設計がなされている。 ※ちなみに、子コンポーネントで親から渡ってきたデータを変更すると Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "totalNumber"(親コンポーネントが再レンダリングされるたびに値が上書きされるため、プロップを直接変更することは避けてください。 代わりに、小道具の値に基づいてデータまたは計算されたプロパティを使用してください。 変更されるプロップ: "totalNumber") というエラーが出る。 Vue.jsでは親→子のコンポーネント間データ受け渡しをする(子が親に依存する)場合、子側で親から渡ってくるデータを変更しないようにオススメしている。 propsでオブジェクト・配列を渡す時は参照渡しになるのでより注意する オブジェクト・配列を変数に格納すると参照渡しになるように、Vue.jsでも親→子でコンポーネント間データ渡しでオブジェクト・配列をpropsで渡すと参照渡しになってしまう。 この場合、子コンポーネントでpropsで渡ってきた値を書き換えた時、親のdataの値も書き換えられるという影響が出るので注意が必要。 ※基本的には上記で述べたように、子側で親から渡ってくるデータを変更しないが原則なので、予期せぬバグを発生させないためにも子側で親から渡ってきたpropsを変更しないようにする。 $emitメソッドのカスタムイベント名はケバブケースで カスタムイベントはHTML上5に書く事になるので、基本的にはHTML側の慣例にならいケバブケースで書くのがオススメ。 Vue.jsの勉強メモ一覧記事へのリンク Vue.jsについて勉強した際に書いた勉強メモ記事のリンクを集約した記事。 https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4 Vueインスタンスに標準で定義されているもの ↩ ソースコード全体を見たい場合はここ ↩ interfaceを見ると$emit(event: string, ...args: any[]): this;となっている第二引数は...args: any[]で、これはarrayだが1つの要素しかない場合はその値が$eventに渡される ↩ 上記の例で言えば、単にthis.$emit("my-click");と書く事もできるという事 ↩ 正確にはsingle file componentのtemplate ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue.js 勉強メモ】$emitメソッドの正体 コンポーネント(子→親)の間のデータ受け渡しでやってる事

はじめに 仕事で使う事になったので1からVue.jsについて学んだ。 ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。 $emitメソッドの正体 コンポーネント(子→親)の間のデータ受け渡しでやってる事 カスタムイベントを定義・発火させることができるメソッド1。 このメソッドを応用して、コンポーネント間(子→親)のデータの受け渡しを行う事ができる。 動画のソースコードは以下2。 parent-component.vue <template> <div> <LikeHeader></LikeHeader> <h2>{{ number }}</h2> <LikeNumber :total-number="number" @my-click="number = $event"></LikeNumber> </div> </template> <script> import LikeHeader from "./components/LikeHeader.vue"; export default { data() { return { number: 10, }; }, components: { LikeHeader, } }; </script> <style scoped> div { border: 1px solid blue; } </style> child-component.vue <template> <div> <p>いいね({{ halfNumber }})</p> <button @click="increment">+1</button> </div> </template> <script> export default { props: ["totalNumber"], computed: { halfNumber() { return this.totalNumber / 2; }, }, methods: { increment() { this.$emit("my-click", this.totalNumber + 1); }, }, }; </script> <style scoped> div { border: 1px solid red; } </style> ここでは、child-component.vue(子)からparent-component.vue(親)へデータの受け渡しを行っている。 上記の考え方としては、 child-component.vueの方で$emitメソッドでカスタムイベントmy-clickを定義し発火させる その際に$emitメソッドでは第二引数を取る事ができるので、第二引数に値this.totalNumber + 1を渡すようにする parent-component.vueでは、v-onディレクティブでカスタムイベントmy-clickが発火した際に何らかの処理を行うように設定する事を考える v-onディレクティブの@hoge=""の""はJavaScriptを書く事ができるのでそこでparent-component.vueのdataプロパティの値を$eventの値に変更するようにする というもの。$emitメソッドでカスタムイベントを発火させた場合、$eventには$emitメソッドの第二引数3の値が渡る仕様になっているので、上記のような考え方で実装する事で、$emitメソッドを応用して「子→親のコンポーネント間データ渡し」が実現できる。 ※補足 $emitメソッドでは第二引数は任意の引数で省略可能4。 つまり、$emitメソッドは純粋にカスタムイベントを定義・発火させるためのメソッドであり、オプションとして第二引数にデータを設定するとイベント発火時に$eventにデータを渡す事ができるというだけ。 子→親のデータの受け渡しは$emitメソッドのカスタムイベント発火機能に便乗して実現されている。 @my-click="number = $event"の書き換え @my-click="number = $event"は以下のような実装に書き換える事もできる。 sample.vue <template> <!-- ・・・ --> <LikeNumber :total-number="number" @my-click="increaseNumber"></LikeNumber> <!-- ・・・ --> </template> <script> // ・・・ }, methods: { increaseNumber(value) { this.number = value; }, }, // ・・・ </script> ※v-onディレクティブのJavaScriptの部分がmethodsプロパティで定義された関数でかつその引数が$eventしかない場合は省略可能なので、上記の実装では@my-click="increaseNumber"と書いている。 propsのように簡単でないのはなぜ? propsを用いると、親→子のコンポーネント間データ渡しが簡単にできるが、その逆(子→親)はなぜ$emitメソッドを使うなど面倒な事をしなければ実現できないのか?という事を思うだろう。 これはVue.jsが、単一方向のデータ渡ししかできないようにする事で、データフローを親→子へのみに限定し、データフローの複雑化を防止してシンプルになるようにしているため。 つまり、Vue.jsのコンポーネントでは、 子は親(のdata)に依存する 親は子(のdata、props)に依存しない という設計がなされている。 ※ちなみに、子コンポーネントで親から渡ってきたデータを変更すると Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "totalNumber"(親コンポーネントが再レンダリングされるたびに値が上書きされるため、プロップを直接変更することは避けてください。 代わりに、小道具の値に基づいてデータまたは計算されたプロパティを使用してください。 変更されるプロップ: "totalNumber") というエラーが出る。 Vue.jsでは親→子のコンポーネント間データ受け渡しをする(子が親に依存する)場合、子側で親から渡ってくるデータを変更しないようにオススメしている。 propsでオブジェクト・配列を渡す時は参照渡しになるのでより注意する オブジェクト・配列を変数に格納すると参照渡しになるように、Vue.jsでも親→子でコンポーネント間データ渡しでオブジェクト・配列をpropsで渡すと参照渡しになってしまう。 この場合、子コンポーネントでpropsで渡ってきた値を書き換えた時、親のdataの値も書き換えられるという影響が出るので注意が必要。 ※基本的には上記で述べたように、子側で親から渡ってくるデータを変更しないが原則なので、予期せぬバグを発生させないためにも子側で親から渡ってきたpropsを変更しないようにする。 $emitメソッドのカスタムイベント名はケバブケースで カスタムイベントはHTML上5に書く事になるので、基本的にはHTML側の慣例にならいケバブケースで書くのがオススメ。 Vue.jsの勉強メモ一覧記事へのリンク Vue.jsについて勉強した際に書いた勉強メモ記事のリンクを集約した記事。 https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4 Vueインスタンスに標準で定義されているもの ↩ ソースコード全体を見たい場合はここ ↩ interfaceを見ると$emit(event: string, ...args: any[]): this;となっている第二引数は...args: any[]で、これはarrayだが1つの要素しかない場合はその値が$eventに渡される ↩ 上記の例で言えば、単にthis.$emit("my-click");と書く事もできるという事 ↩ 正確にはsingle file componentのtemplate ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue × Storage】Storageに画像を保存・取得を実装する

Storageに画像を保存・取得を実装する mypage.vue <img :src="preview" width="200" height="200" class="profile-img" alt="プロフィール画像" /> <label class="profile-txt profile-update">プロフィール画像を編集する <input type="file" @change="onFileChange" style="display:none" /> </label> mypage.vue export default { data() { return { ~ 省略 ~ file: "", profileImage: "", preview: require("../assets/デフォルトの画像.jpg") }; }, methods: { ~ 省略 ~ onFileChange(e) { const image = e.target.files; this.file = image[0]; const S = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; const N = 16; this.uploadUrl = Array.from(crypto.getRandomValues(new Uint32Array(N))) .map(n => S[n % S.length]) .join(""); let self = this; let fileReader = new FileReader(); fileReader.onload = function() { self.preview = fileReader.result; }; fileReader.readAsDataURL(this.file); }, uploadImage() { firebase .storage() .ref(this.uploadUrl) .put(this.file) .then(() => { const profileImage = { uploadUrl: this.uploadUrl, time: firebase.firestore.FieldValue.serverTimestamp() }; firebase .firestore() .collection("users") .doc(this.$route.params.uid) .add({ profileImage: profileImage }); }); } }, ファイルをアップロードするボタンを作成 mypage.vue <input type="file" @change="onFileChange" style="display:none" /> タグのtype属性でtype="file"を指定すると、 ファイル名の入力フィールドと参照ボタンが表示され、サーバーへ送信するファイルを選択できるようになります。 input type=”file”のデザイン自体はHTMLの仕様でそのままCSSを当ててもデザインが変更されないため、 通常のinputタグをdisplay:noneで隠し、隠し要素として配置してます。 mypage.vue <img :src="preview" width="200" height="200" class="profile-img" alt="プロフィール画像" /> <label class="profile-txt profile-update">プロフィール画像を編集する <input type="file" @change="onFileChange" style="display:none" /> </label> タグに対してCSSを適用させるように作成すると自由にデザインをすることが出来ます。 Firebase Storageへ画像を保存 mypage.vue const image = e.target.files; //選択された画像ファイルを選択 this.file = image[0]; //画像ファイルを1つだけ選択 Storageに画像を保存するパスは下記乱数で決めてthis.uploadUrlへ代入してます。 mypage.vue const S ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; const N = 16; this.uploadUrl = Array.from(crypto.getRandomValues(new Uint32Array(N)))  .map(n => S[n % S.length]) .join(""); mypage.vue let self = this; let fileReader = new FileReader(); //FileReaderは、Fileオブジェクトからデータを読み込むことのみを目的としたオブジェクト fileReader.onload = function() { //fileReader.onloadは、読み込みが正常に完了した時に発火するイベント self.preview = fileReader.result; //fileReaderの結果をself.previewへ代入 //関数の中ではfileReaderの[this]を参照してしまうため、一旦[self]に代入して、[this.]の代わりに[self.] とする }; fileReader.readAsDataURL(this.file); //this.fileの値をデータURLとして読み込み、434行目が発火する。 }, mypage.vue uploadImage() { //画像をfirebase storageに保存 firebase .storage() .ref(this.uploadUrl) //さっき決めたパスを参照して、 .put(this.file) //保存する .then(() => { //保存が成功したら、保存した画像ファイルの場所とともにfirestoreに保存する準備 const uploadedImage = { uploadUrl: this.uploadUrl, time: firebase.firestore.FieldValue.serverTimestamp() }; Firestoreへプロフィール画像を保存 上記でStorageに保存された画像情報をFirestoreのコレクションを参照して保存してます。 mypage.vue uploadImage() { //画像をfirebase storageに保存 firebase .storage() .ref(this.uploadUrl) //さっき決めたパスを参照して、 .put(this.file) //保存する .then(() => { //保存が成功したら、保存した画像ファイルの場所とともにfirestoreに保存する準備 const uploadedImage = { uploadUrl: this.uploadUrl, time: firebase.firestore.FieldValue.serverTimestamp() }; // ここでfirebase Firestoreに保存する firebase .firestore() .collection("users") //保存する場所を参照して、 .doc(this.$route.params.uid) //追加で保存setメソッドを使うと上書きされる .set( { name: this.name, sex: this.sex, age: this.age, access: this.access, selfpr: this.selfpr, profession: this.profession, genre: this.genre, favMovie: this.favMovie, time: firebase.firestore.FieldValue.serverTimestamp(), uploadedImage: uploadedImage }, { merge: true } ); }); }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Nuxtでシンタックスハイライト+プレビュー付きのマークダウンエディタを作る

はじめに NuxtでQiitaのようなマークダウンエディター+プレビュー機能のブログを作ろうとした時に、 markdown-it-vueという便利なライブラリがあったので遊んでみました。 最終的にはこんな感じのシンタックスハイライト+プレビュー機能のついたマークダウンエディターを作ります。 コード挿入の黒い背景色やh1タグなどは個人的な好みで後から色を変えています。 このライブラリを導入するだけででマークダウンとシンタックスハイライト、警告ボックスなど簡単に実装できるので、個人開発では試してみるのもアリです。 ただ少しマイナーなライブラリのため、不安な方はmarked.jsとHighlight.jsを組み合わせる方式をとったほうがいいと思います。 markdown-it-vue markdown-it-vue 対応言語はこちらで確認できます。有名な言語には大抵対応しているので困ることはないです。 他にもサポートとして円グラフやシーケンス図が対応しています。 詳しくはREADMEをご覧ください。 実装 まずはnuxtで適当なプロジェクトを作りましょう。 初期設定などは割愛します。 ターミナル $ create-nuxt-app markdown-app markdown-it-vueをインストールします。 ターミナル $ cd markdown-app $ yarn add markdown-it-vue #yarnの場合 $ npm install markdown-it-vue #npmの場合 pages/index.vueをまるっと以下のように書き換えます。 まずは公式のREADMEに書かれてる簡単なサンプルで動作確認しましょう。 pages/index.vue <template> <div> <markdown-it-vue class="md-body" :content="content" /> </div> </template> <script> import MarkdownItVue from 'markdown-it-vue' import 'markdown-it-vue/dist/markdown-it-vue.css' export default { components: { MarkdownItVue }, data() { return { content: '# your markdown content' } } } </script> ターミナル yarn dev #yarnの場合 npm run dev #npmの場合 http://localhost:3000にアクセスすると、以下のようにマークダウンが反映されています。 若干見づらいですが、ボーダーもついていますね。 公式のスタイル一覧はこちら プレビュー機能を作る 簡単なサンプルを載せます。 細かいスタイルは各自で修正してください。 pages/index.vue <template> <div class="wrap"> <div class="editer"> <textarea class="md-editer" v-model="content" placeholder="マークダウンで書く" ></textarea> </div> <div class="preview"> <markdown-it-vue class="md-body" :content="content" /> </div> </div> </template> <script> import MarkdownItVue from "markdown-it-vue"; import "markdown-it-vue/dist/markdown-it-vue.css"; export default { components: { MarkdownItVue }, data() { return { content: "" }; } }; </script> <style lang="scss" scoped> .wrap { width: 100%; height: 800px; display: flex; padding-top: 40px; .editer { width: 50%; .md-editer { width: 100%; height: 100%; border: solid 1px rgb(206, 205, 205); font-size: 1.1rem; } } .preview { width: 50%; height: 100%; border: solid 1px rgb(206, 205, 205); padding: 10px; } } </style> プレビュー機能はtextareaとcontentをv-modelで紐付けることが肝です。 以下の画像の通り、半分より左がエディター、右がプレビューです。 実際にマークダウンで書くと即座に反映されると思います。 実際に公式の書き方を参考に書いてみるとこんな感じ。 これがmarkdown-it-vueのデフォルトスタイルです。 これだけでも十分ですが、私はコード挿入の背景色をQiitaのように黒っぽくしたいと思ったので、独自のCSSを作ることにしました。 もし独自のCSSにしたいと思った方はこの先もお読みください。 独自のCSSを作る assets/markdown.scssを作成して以下をコピペ。 assets/markdown.scss $mainColor: #36cbfa; .md-body { .markdown-body { h1, h2 { border-bottom: none; border-left: solid 10px $mainColor; padding: 5px; } h2 { border: none; color: $mainColor; } pre { background-color: #334146; code { color: rgb(236, 236, 236); font-family: inherit; line-height: 1.8; font-size: 0.9rem; .hljs-keyword { color: rgb(201, 146, 253); } .hljs-title { color: $mainColor; } .hljs-attr { color: rgb(247, 210, 0); } .hljs-attribute { color: palegreen; } .hljs-variable { color: orange; } .hljs-selector-class { color: rgb(214, 157, 50); } .hljs-built_in { color: #d19719; } .hljs-symbol { color: rgb(18, 167, 253); } .hljs-number { color: rgb(172, 255, 172); } .hljs-string { color: rgb(190, 228, 190); } .hljs-subst { color: rgb(250, 99, 89); } .hljs-meta { color: #6594fa; } } } } } nuxt.config.js css: ["@/assets/markdown.scss"]//追記 こんな感じで独自のスタイルが反映されたら成功です! 最後に markdown-it-vueを使えば簡単にマークダウンとシンタックスハイライトが実装できました。 プレビュー機能も実装するとマークダウンの反映が確認できて便利ですね。 皆さんも独自のCSSを割り当てて遊んでみてください。 参考 markdown-it-vue
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsで動的に要素変更

配列に動的に値を追加して描画できなかったので、Obejctにしなさいよという教訓から書きます 間違い等ありましたら、ご指摘していただけると幸いです。 リアクティビティ Vue は、配列における次の変更は検知できません: インデックスと一緒にアイテムを直接セットする場合、例えば vm.items[indexOfItem] = newValue 配列の長さを変更する場合、例えば vm.items.length = newLength 上記の内容に引っかかって配列にひたすらpushして悩んでいました。(ちゃんとドキュメント読もうね...) またリアクティブプロパティの宣言も行っておらず、カオスな状況でしたので原因の発見に遅れました。 Paramedit.vue <template> <form id="form"> <table border="1"> <tr v-for="(sec, index) in task.params" :key="index"> <td>Name</td> <td><input v-model="sec.Name" /></td> <td>Path</td> <td><input v-model="sec.ValueFrom" /></td> <td><button @click.prevent="deleteParam(index)">削除</button></td> </tr> </table> <a @click.prevent="addParam">追加</a> </form> </template> <script> export default { data() { return { // 更新対象 task: { // リアクティブプロパティの宣言必須 // params: [], params: [ { Name: "test1", ValueFrom: "test/path/1" }, { Name: "test2", ValueFrom: "test/path/2" }, ], } addForm: { Name: "", ValueFrom: "" }, }; }, created() {}, methods: { deleteParam: function (id) { let self = this; self.task.params.splice(id, 1); }, addParam: function () { let self = this; self.task.params.push(self.addForm); }, }, }; </script>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

nuxtで使われているvueのバージョン確認をする

vueもnuxtも勉強中の初心者です。 環境:nuxt/cli v2.15.5 結論 下記コマンドで確認 npm list vue vue --version これだとvue/cliの確認になってしまう package.jsonにはnuxtのバージョンしか書いてないし…?と迷っていました
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む