のぐそんブログ

暗いおじさんがシコシコ書くブログです。

Vue.jsのmixinで簡単共通化メモ

mixinで共通化をする

mixin機能を利用することで、複数のコンポーネントで処理を共通化することができます。

使い方

例えば、以下のようなコンポーネントがあり、createdの処理と、methodsを共通化する為mixinにしたいと思います。

<template>
  <div :style="style">{{ name }}
  </div>
</template>
<style>
</style>
<script>

export default {
    created:function(){
      this.setStyle()
      this.setName()
    },
    methods:{
      setStyle(){
        this.style = 'font-size:30px'
      },
      setName(){
        this.name = 'Mixin'
      }
    }
};
</script>

mixin用のオブジェクトを作成

以下のような感じでmixin用のオブジェクトを作成します。

mixin.js
  export const Mixin =  {
    created:function(){
      this.setStyle()
      this.setName()
    },
    methods:{
      setStyle(){
        this.style = 'font-size:30px'
      },
      setName(){
        this.name = 'Mixin'
      }
    }
  }

mixinsに共通処理用のオブジェクトをセットする。

<template>
  <div :style="style">{{ name }}
  </div>
</template>
<style>
</style>
<script>
import {Mixin} from '../mixin'

export default {
  mixins:[Mixin]
};
</script>

mixinのマージのルール

同じメソッドが定義していある場合

mixinとcomponentで同じメソッドが定義している場合は、componentが優先されます。

  export const Mixin =  {
    created:function(){
      this.mtd()  
    },
    methods:{
      mtd(){
        console.log('mixin mtd')
      }
    }
  }
<template>
  <div></div>
</template>
<style>
</style>
<script>
import {Mixin} from '../mixin'

export default {
  mixins:[Mixin],
  methods:{
    mtd(){
      console.log('component mtd') 
    }
  }
};
</script>

以下が出力される。

component mtd
createdに同じ関数が定義されている場合

mixinとcomponentでcreatedに同じ関数が定義されている場合はmixin → componentの順で実行されます。

export const Mixin = {
  created: function () {
    this.mtd('mixin')
  },
  methods: {
    mtd(v) {
      console.log(v)
    }
  }
}
<template>
  <div></div>
</template>
<style>
</style>
<script>
import { Mixin } from "../mixin";

export default {
  mixins: [Mixin],
  created: function() {
    this.mtd('component');
  }
};
</script>

以下が出力される。

mixin
component

mixinの命名規則

mixinの機能を詰め込みすぎると、不要な機能もコンポーネントに入れていしまう可能性がある為、なるべく小さく作るのが良さそうです。 その際に、機能がミックスインの名前からわかるような命名規則にします。

ミックスインの名前の付け方として、「動詞 +able」のような付け方が好ましいようです。

vueのカスタムディレクティブのメモ

カスタムディレクティブ

v-xxxのようなオリジナルのディレクティブを作成することができる。

ディレクティブのオプション

オプション 内容
bind ディレクティブが対象の要素に紐付いたときに1度だけ実行される
inserted 紐ついた要素が挿入されたタイミングで呼ばれる
update ディレクティブの値の変化などに伴って紐ついた要素を含んでいるコンポーネントのVNodeが更新されるタイミングで呼ばれる
componentUpdated コンポーネントのVNodeが更新されたタイミングで呼ばれる
unbind ディレクティブが紐ついた要素から取り除かれたタイミングで呼ばれる

フック関数の引数

引数名 内容
el ディレクティブが紐づく要素
binding 後述

bindingのプロパティ

|プロパティ|内容| |-|-| |name|prefixなし(v-)のディレクティブ名| |velue|ディレクティブに渡される値| |modifiers|修飾子。v-hoge.fugaなら{fuga:true}となる| ※一部です

実装例1) スタイルを設定する

directive.js

ここではグローバルにディレクティブを登録する。

import Vue from 'vue'

Vue.directive('sample',{
  bind: function (el) { 
    el.style.backgroundColor = "red"
  }
})

ディレクティブを利用するには、他と同じくv-をprefixとしてつける。

<template>
  <div>
    <div v-bind:style="hoge" v-sample>テスト</div>
  </div>
</template>
<style>
</style>
<script>
export default {
  data: function() {
    return {
      hoge:'font-size:30px'
    };
  },
};
</script>

結果

f:id:nogson2:20190110170159j:plain

実装例2) 画像がない場合にno imageを出すディレクティブ

Vue.directive('no-image',{
  bind: function (el) { 
    el.addEventListener('error',function(){
      el.src="assets/noimage.png"
    })
  }
})

assets/logo.pngは無いものとする。

<template>
  <div>
    <img v-no-image src="assets/logo.png">
  </div>
</template>

結果

f:id:nogson2:20190110170204j:plain

参考

Vue.js入門 基礎から実践アプリケーション開発まで

vueでtransitionを利用するメモ

vueではtransitionコンポーネントを利用することで、わりと簡単にアニメーションを実現することができます。

公式を見たほうがより詳しいので、公式を見ることをおすすめします。

続きを読む

webpack-dev-serverで立てたサーバーにIPで接続する

webpack-dev-serverでローカルにサーバーを立てた場合、localhostではなくIPでアクセスすると見ることができませんでした。

PCなどはlocalhostでアクセスすれば問題なかったりするのですが、スマホでの動作など外部のデバイスから動作を確認したい場合に少し困ります。

続きを読む

VueでグローバルなCSSを読み込む方法

Vueを利用している場合に、scopedを利用して、CSSカプセル化するのが普通だとおもいますが、その場合bodyhtmlに値を適応することができませんでした。

グローバルにCSSを設定するのに少し悩んだのでメモしておきます。

1. App.vueのscopedを外す

scopedを外せば、当然全ての値がグローバルに展開されます。

2. main.jsでcssをimportする

main.jsでグローバルに展開するcssをimportします。

import './assets/css/global.css'

3. publicフォルダに置いてindex.htmlで読む

静的ファイルとしてpublicフォルダ配下に置いて読み込むようにします。 一番ベーシックな方法かもしれません。

どの方法がよいか

どれでも問題ないかなと思っていますが、私個人としては2番を利用しています。

理由は...
1の場合はApp.vueが大きくなると見通しが悪くなりそうな印象があり、
3は静的ファイルに手を入れるのがなんとなく嫌だったというぼんやりとした理由です。

「Using global style rules in a Vue.js app」が参考になります。