久しぶりに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>
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>
子コンポーネントをローカル化
[親コンポーネント] 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>