- 投稿日:2020-02-10T23:13:38+09:00
Vuefireとは
firebaseとVue.jsを使ったアプリケーションを作っていて、vuefireがどうして必要なのかわからなかったので調べてみました。
vuefireとは
firebaseのリモートデータベースとローカルの状況を用意に一致させるためのツールのことを言います。
firebaseはバックエンド部分を圧倒的に効率化できるサービスですが、そのデータベースとローカルの状況をリアルタイムに同期させるのは多くの工夫が必要となります。
そこで、vuefireを使うと、多くのことを考えることなく、同期作業を行うことができます。どうやってやるのか
まず、npmを使ってvuefireをインストールします。
npm install firebase vuefire@next注意するのは、
vuefire
ではなくてvuefire@next
をインストールすることです。
さらに、これまでは--save
で保存することが必要ですが、 npm5.0からは必要なくなったとのことです。
https://qiita.com/havveFn/items/c5beda8572aa8c1e6be6さらに、vuefireから
firestorePlugin
をインポートします。import { firestorePlugin } from 'vuefire' Vue.use(firestorePlugin)これは、firestoreを使う場合は
firestorePlugin
を、Realtime Databaseを使う場合はrtdbPlugin
をインポートするとのことです。また、
Vue.use(plugin)
で、pluginを有効化することができます。そしてvue内でデータベースのインスタンスを作成します。
export const db = firebase.firestoreこれでvue内でデータベースを触ることができるようになり、vuefireが使えるようになりました。
- 投稿日:2020-02-10T21:02:07+09:00
【Vue.js】VM(view model) をメソッドの引数に渡す方法。
Vue には、
Vue インスタンス
と呼ばれるものがある(vue インスタンスについてはこちら参照)
メソッドの呼び元の Vue インスタンスへのアクセスは極めて簡単であった。
やりたいこと
template から method を呼んで、
呼んだタグを変数で扱いたい。知ってた方法
vue インスタンスは以下のようにして取得ができる。
メソッドのコール元で、引数を指定しなかった場合、
メソッドの第1引数にわかってくるのである。<template> <div v-on:click=clickAction></div> </template> <script> export default { methods: { /** * @param {Object} vm view model */ clickAction(vm) { console.log(vm) } } } </script>知らなかった方法
しかし、呼び元で、vue インスタンス以外の値を引数で渡したい場合はどうなるのか
失敗例
<template> <div v-on:click="clickAction('hoge')"></div> </template> <script> export default { methods: { /** * @param {Object} vm "view model" * @param {String} str "meta variable" */ clickAction(vm, str) { console.log(vm) console.log(str) } } } </script>これだとダメなのですね
実はこれですとconsole.log(vm) => hoge console.log(str) => undefinedとなってしまい、
template
から入れた第1引数は、そのまま第1引数に入ってしまい、
第2引数無しでメソッドを読んでしまいます。成功例
なので答えは以下です。
<template> <div v-on:click="clickAction($event, 'hoge')"></div> </template> <script> export default { methods: { /** * @param {Object} vm "view model" * @param {String} str "meta variable" */ clickAction(vm, str) { console.log(vm) console.log(str) } } } </script>メソッドの引数に
$envent
を渡してあげます。公式 に書いてありました。
時には、インラインステートメントハンドラでオリジナルの DOM イベントを参照したいこともあるでしょう。特別な $event 変数を使うことでメソッドに DOM イベントを渡すことができます:
また1つ賢くなりました。
これで、 メソッド側で DOM にアクションが容易く行えますね。
- 投稿日:2020-02-10T21:02:07+09:00
VM(view model) をメソッドの引数に渡す方法。 js で DOM 操作をしたい人向け
Vue には、
Vue インスタンス
と呼ばれるものがある(vue インスタンスについてはこちら参照)
メソッドの呼び元の Vue インスタンスへのアクセスは極めて簡単であった。
やりたいこと
template から method を呼んで、
呼んだタグを変数で扱いたい。知ってた方法
vue インスタンスは以下のようにして取得ができる。
メソッドのコール元で、引数を指定しなかった場合、
メソッドの第1引数にわかってくるのである。<template> <div v-on:click=clickAction></div> </template> <script> export default { methods: { /** * @param {Object} vm view model */ clickAction(vm) { console.log(vm) } } } </script>知らなかった方法
しかし、呼び元で、vue インスタンス以外の値を引数で渡したい場合はどうなるのか
失敗例
<template> <div v-on:click="clickAction('hoge')"></div> </template> <script> export default { methods: { /** * @param {Object} vm "view model" * @param {String} str "meta variable" */ clickAction(vm, str) { console.log(vm) console.log(str) } } } </script>これだとダメなのですね
実はこれですとconsole.log(vm) => hoge console.log(str) => undefinedとなってしまい、
template
から入れた第1引数は、そのまま第1引数に入ってしまい、
第2引数無しでメソッドを読んでしまいます。成功例
なので答えは以下です。
<template> <div v-on:click="clickAction($event, 'hoge')"></div> </template> <script> export default { methods: { /** * @param {Object} vm "view model" * @param {String} str "meta variable" */ clickAction(vm, str) { console.log(vm) console.log(str) } } } </script>メソッドの引数に
$envent
を渡してあげます。公式 に書いてありました。
時には、インラインステートメントハンドラでオリジナルの DOM イベントを参照したいこともあるでしょう。特別な $event 変数を使うことでメソッドに DOM イベントを渡すことができます:
また1つ賢くなりました。
これで、 メソッド側で DOM にアクションが容易く行えますね。
- 投稿日:2020-02-10T20:03:20+09:00
初心者によるプログラミング学習ログ 235日目
100日チャレンジの235日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
235日目は
おはようございます
— ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) February 9, 2020
235日目
・Vue.jsアプリ模写#早起きチャレンジ#駆け出しエンジニアと繋がりたい#100DaysOfCode
- 投稿日:2020-02-10T15:13:23+09:00
Vue.js で console.log はできないのか?
エラー内容
Vue-CLIで
console.log
をしようとしたところ以下のエラーがでました。Module Error (from ./node_modules/eslint-loader/index.js): error: Unexpected console statement (no-console) at src/components/About.vue:11:5: 9 | export default { 10 | deactivated() { > 11 | console.log("deactivated"); | ^ 12 | } 13 | }; 14 | </script>JSで頻発する
console.log
が使えないって本当? と思い調べてみると、Vue-CLIの初期設定では無効になっているそうです。なるほど。以下
console.log
を有効化する手順を残します。解決策
【手順1】 package.json に追記
package.json
の"rules"のなかに1行追加します(コメントアウトで記しています)。package.json{ "name": "udemy-vuejs", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint" }, "dependencies": { "core-js": "^3.4.4", "vue": "^2.6.10" }, "devDependencies": { "@vue/cli-plugin-babel": "^4.1.0", "@vue/cli-plugin-eslint": "^4.1.0", "@vue/cli-service": "^4.1.0", "babel-eslint": "^10.0.3", "eslint": "^5.16.0", "eslint-plugin-vue": "^5.0.0", "vue-template-compiler": "^2.6.10" }, "eslintConfig": { "root": true, "env": { "node": true }, "extends": [ "plugin:vue/essential", "eslint:recommended" ], "rules": { "no-console": 0 // ← この行を追加する!! }, "parserOptions": { "parser": "babel-eslint" } }, "browserslist": [ "> 1%", "last 2 versions" ] }【手順2】 サーバーを立ち上げ直す
サーバーを起動している場合は
control + c
で抜けてから、通常通り以下のコマンドで再度起動します。$ npm run serve再起動しないとうまく動作しませんでした。ここまでセットで行いましょう。
参考
主に以上の記事を参考にさせていただきました。ありがとうございます。
さいごに
私自身Vue.js初心者で、エラー文から探すのに戸惑ったことと、再起動も必要というところもセットでわかると良いなと思ったため残しておきます。これから学習される方の参考になれば幸いです。
- 投稿日:2020-02-10T12:47:39+09:00
【Vue.js】簡単な税込み・割り勘計算アプリを作る
前置き
Vueの基礎文法の復習として以下の要件の税込み・割り勘計算アプリを作りました。
コンポーネントやcomputed、methods、v-on、v-modelなどの簡単な解説も添えたので、Vue初学者の参考になるかと思います。要件
任意の数と人数が入力されたときに以下の二つの出力をできるようにする。(数、人数ともに整数とする)
1.税込みの値
2.税込み金額を人数で割った値本編
さて、実際に作成に入っていきましょう。
一旦、完成物のコードを見て頂き、それを沿って解説を入れていこうと思います。完成版ソースコード
<!DOCTYPE html> <html> <head> <title>My first Vue app</title> <script src="https://unpkg.com/vue"></script> <style> .title{ margin-top: 10px; margin-bottom: 10px; font-size: 24px; } #app{ position: relative; } .type{ margin-top: 3px; margin-bottom: 1px; } .coution_num{ position: absolute; top: 15px; left: 165px; color: red; font-size: 10pt; } .coution_people{ position: absolute; top: 67px; left: 165px; color: red; font-size: 10pt; } button{ display: inline-block; width: 100px; margin-top: 5px; margin-left: 0px; margin-right: 0px; } .text_tax{ position: absolute; top:125px; font-size: 20px; } .text_exam{ position: absolute; top:160px; font-size: 20px; } </style> </head> <body> <h1 class="title">「税込み、割り勘」計算サイト</h1> <div id="app"> <Calculation /> </div> <script> var calc = Vue.component('Calculation', { data:function(){ return{num:'',tax_num:0,people_num:1,exam:0,flag_tax:false,flag_division:false}; }, computed:{ tax:function(event){ tax_num = this.num * 1.10; console.log(tax_num) return Math.floor(tax_num); }, exam_2:function(event){ tax_num = this.num * 1.10; exam = tax_num / this.people_num; console.log(exam); return Math.ceil(exam); }, }, methods:{ doAction:function(event){ this.flag_tax = !this.flag_tax; }, doAction_2:function(event){ this.flag_division = !this.flag_division; } }, template:'<div>\ <p class="type">金額を入力してください</p>\ <div><input type="number" min="1" v-model="num"></div>\ <p class="coution_num" v-if="num < 0">※0以上の値を入れてください</p>\ <p class="type">人数を入力してください</p>\ <div><input type="number" min="1" v-model="people_num"></div>\ <p class="coution_people" v-if="people_num <= 0">※1以上の値を入れてください</p>\ <button v-on:click="doAction">税込み</button>\ <button v-on:click="doAction_2">割り勘</button>\ <p v-if="flag_tax && num >= 0" class="text_tax">税込み:{{tax}}円です</p>\ <p v-if="flag_division && num >= 0 &&people_num > 0" class="text_exam">一人当たり:{{exam_2}}円です</p>\ </div>' }) var app = new Vue({ el:'#app', }) </script> </body> </html>解説
コンポーネントの出力
61~63行目:
以下の記述をすることで、「Calculationコンポーネント」を呼び出しています。
<div id="app"> <Calculation /> </div>65~106行目:
HTMLとして出力される部分は、templateとして記述しています。
templateの中に書かれているHTMLが62行目に Calculation として呼び出されている形になります。template:'<div>\ <p class="type">金額を入力してください</p>\ <div><input type="number" min="1" v-model="num"></div>\ <p class="coution_num" v-if="num < 0">※0以上の値を入れてください</p>\ <p class="type">人数を入力してください</p>\ <div><input type="number" min="1" v-model="people_num"></div>\ <p class="coution_people" v-if="people_num <= 0">※1以上の値を入れてください</p>\ <button v-on:click="doAction">税込み</button>\ <button v-on:click="doAction_2">割り勘</button>\ <p v-if="flag_tax && num >= 0" class="text_tax">税込み:{{tax}}円です</p>\ <p v-if="flag_division && num >= 0 &&people_num > 0" class="text_exam">一人当たり:{{exam_2}}円です</p>\ </div>' })v-modelにて入力値が即時に反映されるようにする
94,97行目
上記のtemplateタグ内にてv-modelを使っています。
この構文はinputタグに入力された値をVueのdataプロパティの値やコンポーネントの変数にバインドする機能で、この機能を使用することで入力された値をリアルタイムに表示することができます。今回はコンポーネント内の変数である「num(入力された金額)」、「people_num(割り勘の人数)」がinputに入力される度に変更が反映されています。
v-onにてボタンクリック時にイベントが起きるようにする
99~100行目
<button v-on:click="doAction">税込み</button>\ <button v-on:click="doAction_2">割り勘</button>\v-onデレクティブは、イベントの属性に値をバインドする機能であり、この機能を使用することでVueオブジェクト内やコンポーネント内の変数を使用できるようになります。
今回はbuttonタグがクリックされた際に、「doAction」と「doAction_2」が発火するように記述しています。
「doAction」と「doAction_2」の具体的な処理はmethods内にて記述していきます。なぜonclickが使えないのか??
今回、buttonタグをクリックした時にイベントが起きるようにしたいんですが、カウンター変数の値を増やそうとする時は「onclick」を使用しても上手く作動しません。
これはVueのコンポーネント内のdataプロパティで定義した値はコンポーネント内でしか使えないため、コンポーネントの外部であるonclickによってカウンター変数を使うことは出来ないからです。
このような場合にv-onディレクティブを使用します。
イベント名にはHTMLタグなどで使用するイベント名の「on」を取り除いた物を使用します。
例としては、「onclick→click」。computedにて計算を行う
70行目~81行目:
computed:{ tax:function(event){ tax_num = this.num * 1.10; console.log(tax_num) return Math.floor(tax_num); }, exam_2:function(event){ tax_num = this.num * 1.10; exam = tax_num / this.people_num; console.log(exam); return Math.ceil(exam); }, },computed(算術プロパティ)を使用しています。
今回は、「tax(入力値に税率をかける処理)」と「exam_2(入力値に税率値をかけた値を入力された人数で割る処理)」の二種類を定義していて、それぞれの値をreturnで返しています。
このようにreturnで返した値をtemplete内で使用しています。
また、「this.変数名」はコンポーネント内の変数で、「num(入力された金額)」、「people_num(割り勘の人数)」を持ってきています。console.logの部分は計算値の確認の為に、記述しています。
methodsにてボタンが押された時の処理を書く
83行目~90行目:
methods:{ doAction:function(event){ this.flag_tax = !this.flag_tax; }, doAction_2:function(event){ this.flag_division = !this.flag_division; } },methodを使用して、税込みボタンと割り勘ボタンが押された時の処理を書いています。
先ほどのv-onにて設定された「doActuon」と「doAction_2」の具体的な処理が書いてある形です。処理内容は「ボタンを押した時に判定値が反転する処理」としていて、これによってボタンを押した時に、templete内のv-ifでの条件分岐が行われるようにしています。
終わりに
現在、定期的にVue初学者向きのコンテンツを発信しているので、興味ある方はぜひ!!
Twitter:https://twitter.com/teriteriteriri
ブログ:https://terrblog.com/また、今回の試みは自身の学習のために作った事もある為、指摘やアドバイス等、お待ちしております。
- 投稿日:2020-02-10T11:20:42+09:00
【Vue.js】v-forで配列をn個ずつ描画する
やりたいこと
このように、配列をn個(今回は3個)並べたら改行したい。
前提:配列はAPI等で受け取るデータで、何個来るかわからない。v-forで描画するまでやってる記事は見かけなかったのでメモです。
そのままv-for
<template> <div> <div v-for="(item, index) in array" :key="index"> <li>{{ item }}</li> </div> </div> </template> <script> export default { data() { return { array: [ 'AMETHYST', 'BLUE-SAPPHIRE', 'CITRIN', 'DIAMOND', ... ] } } } </script>配列分割して3個ずつv-for
computedで配列を3個ずつに分割し、それをさらに配列に入れたものを作ります。
配列の中に配列を作るイメージ。computed: { groupedArray() { const base = this.array.length const split_cnt = 3 // 何個ずつに分割するか const grouped_array = [] for (let i=0; i<Math.ceil(base/split_cnt); i++) { let multiple_cnt = i * split_cnt // 3の倍数 // (i * 3)番目から(i * 3 + 3)番目まで取得 let result = this.array.slice(multiple_cnt, multiple_cnt + split_cnt) grouped_array.push(result) } return grouped_array // [ // ["AMETHYST", "BLUE-SAPPHIRE", "CITRIN"], // ["DIAMOND", "EMERALD", "FIRE-OPAL"], ... // ] } }外側の配列でv-forし、その中で内側の配列をv-forします(伝われ)。
<div v-for="(items, index) in groupedArray" :key="index"> <li v-for="(item, index) in items" :key="index"> {{ item }} </li> </div>おわり。
さいごに
画像をサムネイル表示するときに使いました。
みなさまのご参考になれば幸いです。参考記事
- 投稿日:2020-02-10T06:25:16+09:00
【Rails】Railsに保存した画像ファイルをVue.js側で表示するサンプルコード(Base64、Active Storage使用)
はじめに
Rails APIモード→Vue.jsでの画像データのやりとりをする方法を残します。(Base64、Active Storage使用)
今回の対象
Vue.js→Rails(こちらの記事をご参照下さい。引用失礼します!)
Rails→Vue.js ←ココ環境
OS: macOS Catalina 10.15.3 Ruby: 2.6.5 Rails: 6.0.2.1 Vue: 2.6.10 axios: 0.19.0前提:実施済とみなすこと
※引用記事の例を使用します。
rails new
- Active Storageのインストール
Post
モデルの作成- Vue.jsのインストールと利用するための準備
eyecatch
として画像ファイルがPost
モデルのインスタンスに添付されている- (今ココ)
1.【Rails】画像ファイルをBase64形式でエンコードするメソッドを定義する
base64_module.rb# 各モデルのレコードに添付された画像ファイルをBase64でエンコードする def encode_base64(image_file) image = Base64.encode64(image_file.download) # 画像ファイルをActive Storageでダウンロードし、エンコードする blob = ActiveStorage::Blob.find(image_file[:id]) # Blobを作成 "data:#{blob[:content_type]};base64,#{image}" # Vue側でそのまま画像として読み込み出来るBase64文字列にして返す end2.【Rails】Active Storageでアタッチした画像ファイルを読み込み
posts#show
で投稿データを返すとします。posts_controller.rbdef show post = Post.find(params[:id]).as_json #JSON形式にしておく eyecatch = post.eyecatch #eyecatchは添付した画像ファイル if eyecatch.present? post['image'] = encode_base64(eyecatch) # 画像ファイルを1.で定義したメソッドでBase64エンコードし、renderするデータに追加する end render json: post end3.【Rails】ルーティングを設定
Rails.application.routes.draw do # 略 get 'posts', to: 'posts#show' # 略 end4.【Vue.js】画像を取得し、表示するコンポーネントを作成
show.vue<template> <div> <p>投稿表示フォーム</p> <!-- preventでsetPost()メソッドがページ遷移なく発火する --> <form v-on:submit.prevent="setPost()"> <p> <label>Title</label> <input name="post.title" type="text" v-model="post.title"><br /> </p> <p> <label>Body</label> <input name="post.body" type="text" v-model="post.body"><br /> </p> <!-- post.idを指定して... --> <p> <label>IDを指定</label> <input name="post.id" type="text" v-model="post.id"> </p> <!-- ここを押してデータ取得 --> <input type="submit" value="ここを押して投稿データ取得" > <!-- Base64形式であればimgタグでそのまま読み込みが可能 --> <img :src="post.image" alt="post.image"> </form> </div> </template> <script> import axios from 'axios' export default { name: 'sample', data() { return { post: {}, } }, methods: { setPost() { axios.get('/posts', {params: {id: this.post.id}}) //入力したidに応じてpostが返ってくる .then(response => { this.post = response.data }) .catch( error => { console.error(error) }) } } } </script>※実際は自分で
id
を指定することはないと思いますので、状況に応じて変更して頂ければと思います。以上です!
おわりに
最後まで読んで頂きありがとうございました
どなたかの参考になれば幸いです
参考にさせて頂いたサイト(いつもありがとうございます)
- 投稿日:2020-02-10T04:33:49+09:00
既存オブジェクトにプロパティを追加してもリアクティブにならない時の対処
See the Pen 既存オブジェクトにリアクティブなプロパティを追加するテスト by mykysyk (@mykysyk) on CodePen.