20200210のvue.jsに関する記事は9件です。

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が使えるようになりました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【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 にアクションが容易く行えますね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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 にアクションが容易く行えますね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 235日目

100日チャレンジの235日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

235日目は

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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 CLIでconsole.logを有効化する方法

主に以上の記事を参考にさせていただきました。ありがとうございます。

さいごに

私自身Vue.js初心者で、エラー文から探すのに戸惑ったことと、再起動も必要というところもセットでわかると良いなと思ったため残しておきます。これから学習される方の参考になれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【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/

また、今回の試みは自身の学習のために作った事もある為、指摘やアドバイス等、お待ちしております。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Vue.js】v-forで配列をn個ずつ描画する

やりたいこと

kiji.jpg

このように、配列を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>

おわり。

さいごに

画像をサムネイル表示するときに使いました。
みなさまのご参考になれば幸いです。

参考記事

配列をn個ずつの配列に分割して、それをまとめた配列を作る

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】Railsに保存した画像ファイルをVue.js側で表示するサンプルコード(Base64、Active Storage使用)

はじめに

Rails APIモード→Vue.jsでの画像データのやりとりをする方法を残します。(Base64、Active Storage使用)

今回の対象

:x: Vue.js→Rails(こちらの記事をご参照下さい。引用失礼します!)
:o: 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文字列にして返す
  end

2.【Rails】Active Storageでアタッチした画像ファイルを読み込み

posts#showで投稿データを返すとします。

posts_controller.rb
  def 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
  end

3.【Rails】ルーティングを設定

Rails.application.routes.draw do
# 略
  get 'posts', to: 'posts#show'
# 略
end

4.【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を指定することはないと思いますので、状況に応じて変更して頂ければと思います。

以上です!

おわりに

最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

参考にさせて頂いたサイト(いつもありがとうございます)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

既存オブジェクトにプロパティを追加してもリアクティブにならない時の対処

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む