Vue」タグアーカイブ

[Vue] 親コンポーネントのデータ/メソッドを子コンポーネントから使う

前提

以下の環境で動作確認

要素 バージョン
debian 8.6
node 8.6.0
Vue 2.6.1

概要

題の通り、Vueの親子コンポーネント間でのデータとメソッドのやり取りを行う方法の備忘録。
本記事では、以下のようなVueコンポーネントの親子関係を用意し、子コンポーネントから親コンポーネントのデータ、メソッドを利用する。

  • 親コンポーネント(parent)
    — 文字列データ及びそれを書き換えるメソッドを定義
  • 子コンポーネント(child)
    — テキストボックスとボタンと持ち、親のデータの読み書きを行う

親コンポーネント

<template>
  <div>
    <child :data="data" @set="setData"/>
  </div>
</template>

<script>
  export default {
    name: 'parent',
    data() {
      return {
        data: '',
      }
    },
    methods: {
      setData(data) {
        this.data = data
      }
    }
  }
</script>

子コンポーネント(child)に、属性dataとメソッドsedDataを渡す。
:dataと@setは省略記法で、それぞれv-bind:dataと、v-on:setを省略したもの

子コンポーネント

<template>
  <div>
    <input type="text" ref="text">
    <button @click="$emit('set', $refs.text.value)">Set</button>
    <p>{{ data }}</p>
  </div>
</template>

<script>
  export default {
    name: 'child',
    props: ['data'],
  }
</script>

親コンポーネントから受け取る属性は、propsで定義しなければならない。一見面倒だが、これによって不要な属性を受け取らずに済む。

buttonクリック時に、親コンポーネントのイベントに伝搬するために、$emitを用いる。$emitの第二引数以降が、元のイベントに対する引数になる。

実行結果

画像のように、テキストボックスに文字列を入力し、ボタンをクリックすると、親コンポーネントのsetDataメソッドが実行され、dataが書き換わる。

備考

  • Vueではコンポーネントの親子関係が深くなるとバケツリレーが始まるので、Vuexを導入が推奨されるみたい
  • VuexはReactにおけるReduxのような、Vueでストアを一元化するためのフレームワーク

WebPack + Vueで、「Element」導入時にハマった点

前提

以下環境にて確認

要素 バージョン
debian 8.6
node 8.2.1
npm 5.3.0

概要

Webpackを用いてVueアプリを開発している中で、Vue2.0用のUIライブラリであるElementを導入しようとしたら、Webpack周りでハマったので導入手順と解決手順を備忘録に残す。

備忘録が主な目的なので、Webpack,Vue,Elementなどに関する説明は割愛

Elementの導入

npmでインストールする

npm install element-ui -s

エントリポイントでElement関連をimport

import ElementUI  from 'element-ui'
import locale     from 'element-ui/lib/locale/lang/ja'
import 'element-ui/lib/theme-default/index.css'

Elementの利用を宣言。localeを指定することで日本語が有効になるらしい

Vue.use(ElementUI, {locale});

エラー① Element内のCSSファイルが解決できない

この状態でwebpackを回すと、以下のエラーが出る

ERROR in ./node_modules/element-ui/lib/theme-default/index.css
Module parse failed: /root/degulog/node_modules/element-ui/lib/theme-default/index.css Unexpected character '@' (1:0)
You may need an appropriate loader to handle this file type.

どうやらElementに付随するCSSファイルをバンドルできないらしい。

原因は単純に、これまでscssだけ使ってたのでcssに対するローダーをwebpackで設定していなかったため。
なのでwebpack.config.jsのloadersに以下を追加すれば解決

{ test: /\.css$/, loader: 'style-loader!css-loader' },

エラー② Element内のwoffファイルが解決できない

続けて以下のエラーが発生した

ERROR in ./node_modules/element-ui/lib/theme-default/fonts/element-icons.woff?t=1472440741
Module parse failed: /root/degulog/node_modules/element-ui/lib/theme-default/fonts/element-icons.woff?t=1472440741 Unexpected character '' (1:4)
You may need an appropriate loader to handle this file type.

問題の本筋は前項と同様。woffを解決するローダが設定されていなかった。

url-loaderを適用すれば良いが、まずそれが入っていなかたのでインストールする。

$ npm install url-loader

で、webpack.config.jsonのloadersに以下を追加。woff意外にも対応できるように汎用的に記述。

{
  test: /\.(otf|eot|svg|ttf|woff|woff2)(\?.+)?$/,
  loader: 'url-loader'
},

動作確認

依存解決も上手く行って、以下のようにElementが利用できた。
例はDatetimePickerコンポーネント

<el-date-picker
  v-model="value1"
  type="datetime"
  placeholder="Select date and time">
</el-date-picker>