LoginSignup
2
0

More than 3 years have passed since last update.

Vueのコンポーネント作成(基礎)

Last updated at Posted at 2020-04-24

久しぶりにvueでコード書いたら、いろいろドンづまったのでメモ

箱型を作成

まずは最もシンプルなvueを作成します。
しばらくはjavascriptをHTMLと同じファイルに作成します。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>vueを学ぶ</title>
</head>

<body>
  <div id="app">
    {{perfume[0].name}}
  </div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
  el: '#app',
  data: {
    perfume: [{name:"かしゆか"},{name:"あ〜ちゃん"},{name:"のっち"}]
  },
})
</script>
</body>
</html>

ブラウザで開くと、"かしゆか"だけ表示されます。

グローバル子コンポーネントを作成

次に子コンポーネントを作成します。(まずはグローバルから)
子コンポーネントは、以下のような形です。
"component-name"はケバブ方式で書きましょう(大文字を入れるとエラーを起こします)

Vue.component('component-name',{
  template:"",
  props:""
})

こちらが作成例です。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>vueを学ぶ</title>
</head>

<body>
  <div id="app">
    {{perfume[0].name}}

+    <perfume-member></perfume-member>
  </div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
+Vue.component('perfume-member',{
+  template:"<h1>コンポーネント</h1>"
+}
+)

new Vue({
  el: '#app',
  data: {
    perfume: [{name:"かしゆか"},{name:"あ〜ちゃん"},{name:"のっち"}]
  },
})
</script>
</body>
</html>

親コンポーネントからデータを渡す

親コンポーネントからデータを渡すには、
[html側] v-bindでデータの受け渡しを記述
v-bindは左に子コンポーネントでのデータ名、右側に親コンポーネントでのデータ名です。
<perfume-member v-bind:members="perfume"></perfume-member>

[js側] 子コンポーネントはpropsで受け取る。

props:{
  members:""
}

ここまでのコードです。
子コンポーネントのtemplateの部分は受け取ったデータを表示させるために
"<h1>{{member[1].name}}</h1>"と書き換えました

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>vueを学ぶ</title>
</head>

<body>
  <div id="app">
    {{perfume[0].name}}

 +   <perfume-member v-bind:member="perfume"></perfume-member>
  </div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('perfume-member',{
+  template:"<h1>{{member[1].name}}</h1>",
+  props:{
+      members:"",
+    }
  }
)

new Vue({
  el: '#app',
  data: {
    perfume: [{name:"かしゆか"},{name:"あ〜ちゃん"},{name:"のっち"}]
  },
})
</script>
</body>
</html>

IMAGE

templateをx-templateに

現実のプログラムでは、templateを子コンポーネント内に直接記載することはまずなく、別ファイルに保管します。

[子コンポーネント] templateプロパティをtemplate:"#templateのid名"にします。
[x-template]テンプレートファイルを作成します。
(ちなみにxとは、標準化されてないMIMEタイプに慣習的に付けられる名前です)

こんな感じで作成しました。
注意!! x-templateの中身は<div>〜</div>などタグで囲む必要があります。
(囲んでなかった時には、以下のようなエラーメッセージが出ます。one root elementって要は一つのDOM要素って意味なんですね)
「[Vue warn]: Error compiling template:

Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.」)

<script type="text/x-template" id="perfume-detail">
  <div>
    <h1>Perfumeのメンバー</h1>
    <ul>
      <li v-for="member in members">{{member.name}}</li>
    </ul>
  </div>
</script>

x-templateの記述は子コンポーネントより前にする必要があります。
(後にすると、x-templateがありませんとエラーがでます)

ここまでのコードはこちら。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>vueを学ぶ</title>
</head>

<body>
  <div id="app">
-    {{perfume[0].name}} //もう不要なので消します 
-
    <perfume-member v-bind:members="perfume"></perfume-member>
  </div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

+<script type="text/x-template" id="perfume-detail">
+    <h1>Perfumeのメンバー</h1>
+    <ul>
+      <li v-for="member in members">{{member.name}}</li>
+    </ul>
+</script>

<script>
Vue.component('perfume-member',{
  template:"#perfume-detail",
  props:{
      members:"",
    }
  }
)

new Vue({
  el: '#app',
  data: {
    perfume: [{name:"かしゆか"},{name:"あ〜ちゃん"},{name:"のっち"}]
  },
})
</script>

</body>
</html>

IMAGE

子コンポーネントをローカル化

[親コンポーネント] componentsプロパティを追加

components:{
  "コンポーネント名":コンポーネント関数名
}

[子コンポーネント ]Vue.componentを削除し、ローカル関数として定義する

const コンポーネント名={
 template:・・・
}

コードはこんな感じです
(scriptタグ内のみを抜粋)

<script>
-Vue.component("perfume-member",
+const perfume={
  template:"#perfume-detail",
  props:{
      members:"",
    },
  }

new Vue({
  el: '#app',
  data: {
    perfume: [{name:"かしゆか"},{name:"あ〜ちゃん"},{name:"のっち"}]
  },
+ components:{
+   "perfume-member":perfume,
+ }
})
</script>

子コンポーネントのデータ設定

親から受け取らず、子コンポーネント独自に定めるデータの記述方法です。
dataプロパティはfunctionでオブジェクトを返すようにします。
(アロー関数を使った書き方もできます)

  data:()=>{
    return {
      songs:[{title:"TOKYO GIRL"},{title:"Spring of Life"},{title:"FLASH"}]
      }
    }

コード全体です。
x-templateにはdataを表示させるようにしました。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>vueを学ぶ</title>
</head>

<body>
  <div id="app">
    <perfume-member v-bind:members="perfume"></perfume-member>
  </div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script type="text/x-template" id="perfume-member">
  <div>
    <h1>Perfume</h1>
    <h2>メンバー</h2>
    <ul>
      <li v-for="member in members">{{member.name}}</li>
    </ul>
+    <h2></h2>
+    <ul>
+      <li v-for="song in songs">{{song.title}}</li>
+    </ul>
  </div>
</script>

<script>
const perfume={
  template:"#perfume-member",
  props:{
      members:"",
    },
+  data:()=>{
+    return {
+      songs:[{title:"TOKYO GIRL"},{title:"Spring of Life"},{title:"FLASH"}]
+      }
+    }
}

new Vue({
  el: '#app',
  data: {
    perfume: [{name:"かしゆか"},{name:"あ〜ちゃん"},{name:"のっち"}]
  },
  components:{
    "perfume-member":perfume,
  }
})
</script>

</body>
</html>

IMAGE

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0