初心者向けVue.jsレッスン7:計算されたプロパティ
→初心者向けVue.jsレッスン8:コンポーネント
レッスンの目的
このレッスンの主な目標は、最初のコンポーネントを作成し、データをコンポーネントに渡すためのメカニズムを調べることです。
初期コード
開始
index.htmlするタグに
あるファイルコードは次の<body>とおりです。
<div id="app">
<div class="product">
<div class="product-image">
<img :src="image" />
</div>
<div class="product-info">
<h1>{{ title }}</h1>
<p v-if="inStock">In stock</p>
<p v-else>Out of Stock</p>
<p>Shipping: {{ shipping }}</p>
<ul>
<li v-for="detail in details">{{ detail }}</li>
</ul>
<div
class="color-box"
v-for="(variant, index) in variants"
:key="variant.variantId"
:style="{ backgroundColor: variant.variantColor }"
@mouseover="updateProduct(index)"
></div>
<button
v-on:click="addToCart"
:disabled="!inStock"
:class="{ disabledButton: !inStock }"
>
Add to cart
</button>
<div class="cart">
<p>Cart({{ cart }})</p>
</div>
</div>
</div>
</div>
コードは
main.js次のとおりです。
var app = new Vue({
el: '#app',
data: {
product: 'Socks',
brand: 'Vue Mastery',
selectedVariant: 0,
details: ['80% cotton', '20% polyester', 'Gender-neutral'],
variants: [
{
variantId: 2234,
variantColor: 'green',
variantImage: './assets/vmSocks-green.jpg',
variantQuantity: 10
},
{
variantId: 2235,
variantColor: 'blue',
variantImage: './assets/vmSocks-blue.jpg',
variantQuantity: 0
}
],
cart: 0,
},
methods: {
addToCart() {
this.cart += 1;
},
updateProduct(index) {
this.selectedVariant = index;
console.log(index);
}
},
computed: {
title() {
return this.brand + ' ' + this.product;
},
image() {
return this.variants[this.selectedVariant].variantImage;
},
inStock(){
return this.variants[this.selectedVariant].variantQuantity;
}
}
})
仕事
Vueアプリケーションのすべてのデータ、メソッド、計算されたプロパティをルートVueインスタンスに配置する必要はありません。時間が経つにつれて、これは保守が非常に困難になるコードにつながります。代わりに、コードをモジュール化された部分に分割して、操作が簡単になり、開発がより柔軟になるようにします。
問題の解決策
まず、既存のコードを新しいコンポーネントに移動することから始めましょう。
これは、
main.jsコンポーネントがファイルに登録される方法です。
Vue.component('product', {})
最初の引数は、選択したコンポーネント名です。2つ目は、前のチュートリアルでVueをインスタンス化するために使用したものと同様のオプションオブジェクトです。
Vueインスタンスでは、プロパティを使用
elしてDOM要素へのバインディングを整理しました。コンポーネントの場合、コンポーネントtemplateのHTMLコードを定義するプロパティが使用されます。
オプションを使用して、オブジェクトのコンポーネントテンプレートを説明しましょう。
Vue.component('product', {
template: `
<div class="product">
… // HTML-, product
</div>
`
})
Vueでテンプレートを作成する方法はいくつかあります。現在、テンプレートリテラルを使用しており、その内容は後引用符で囲まれています。
テンプレートコードが
<div>クラスを持つ要素などの単一のルート要素に配置されないことが判明した場合product、次のエラーメッセージが表示されます。
Component template should contain exactly one root element
つまり、コンポーネントテンプレートは1つの要素のみを返すことができます。
たとえば、次のテンプレートは1つの要素のみで表されるため、整形式です。
Vue.component('product', {
template: `<h1>I'm a single element!</h1>`
})
ただし、テンプレートに複数の兄弟が含まれている場合は機能しません。悪いパターンの例を次に示します。
Vue.component('product', {
template: `
<h1>I'm a single element!</h1>
<h2>Not anymore</h2>
`
})
その結果、テンプレートに多くの要素、たとえば
<div>クラスproductに含まれる要素のセットを含める必要がある場合、これらの要素は外部コンテナ要素に配置する必要があることがわかります。その結果、テンプレートにはルート要素が1つだけ含まれます。
テンプレートに、以前はファイルにあったHTMLコードが含まれているので、
index.html以前はルートVueインスタンスにあったコンポーネントにデータ、メソッド、計算されたプロパティを追加できます。
Vue.component('product', {
template: `
<div class="product">
…
</div>
`,
data() {
return {
//
}
},
methods: {
//
},
computed: {
//
}
})
ご覧のとおり、このコンポーネントの構造は、以前に使用したVueインスタンスの構造とほぼ同じです。
dataこれがプロパティではなく、オプションを持つオブジェクトのメソッドになっていることに気づきましたか?なぜそうなのですか?
重要なのは、コンポーネントは、それらを再利用する計画で作成されることが多いということです。多くのコンポーネントがある場合は
product、各コンポーネントに独自のエンティティインスタンスがあることを確認する必要がありますdata。これdataはデータを含むオブジェクトを返す関数になっているため、各コンポーネントは独自のデータセットを受け取ることが保証されています。エンティティがdata関数ではなかった場合、各コンポーネントproduct、そのようなコンポーネントが使用された場合は常に、同じデータが含まれます。これは、再利用可能なコンポーネントの考えに反します。
製品関連のコードをネイティブコンポーネント
productに移動したので、ルートVueインスタンスを記述するためのコードは次のようになります。
var app = new Vue({
el: '#app'
})
ここで、コンポーネント
productをファイルコードに配置する必要がありますindex.html。次のようになります。
<div id="app">
<product></product>
</div>
ここでアプリケーションページをリロードすると、前のフォームに戻ります。

アプリケーションページ
Vue開発者ツールを調べると、ルートエンティティと製品コンポーネントがあることがわかります。

Vue Developer Toolsを使用したアプリケーションの分析
ここで、コンポーネントの再利用性を示すために、コードに
index.htmlさらにいくつかのコンポーネントを追加しましょうproduct。実際、これがコンポーネントの再利用の編成方法です。コードindex.htmlは次のようになります。
<div id="app">
<product></product>
<product></product>
<product></product>
</div>
そして、ページには製品カードの3つのコピーが表示されます。

1ページに複数の製品カードが表示される
将来的には1つのコンポーネント
productで作業するため、コードindex.htmlは次のようになります。
<div id="app">
<product></product>
</div>
仕事
多くの場合、アプリケーションは、親エンティティからデータ、入力パラメータを受け入れるためのコンポーネントを必要とします。この場合、コンポーネントの親は
productルートVueインスタンス自体です。
ルートVueインスタンスにいくつかのデータの説明を持たせます。このデータは、ユーザーがプレミアムアカウントの所有者であるかどうかを示します。 Vueインスタンスを記述するためのコードは次のようになります。
var app = new Vue({
el: '#app',
data: {
premium: true
}
})
プレミアムユーザーが送料無料の資格があることを決定しましょう。
これは
product、premiumルートVueインスタンスプロパティに書き込まれる内容に応じて、コンポーネントが異なる送料情報を出力することを意味します。ルートVueインスタンス
プロパティに保存されているデータを
premiumコンポーネントである子に送信するにはどうすればよいproductですか?
問題の解決策
Vueでは、親エンティティから子にデータを転送
propsするために、コンポーネントによって記述されたオプションを持つオブジェクトプロパティが使用されます。これは、コンポーネントの入力パラメーターを記述するオブジェクトであり、その値は、親エンティティから受信したデータに基づいて設定する必要があります。
コンポーネントが受け取ると予想される入力パラメータの種類を説明することから始めましょう
product。これを行うには、オブジェクトの作成時に使用されるオプションを使用して、対応するプロパティをオブジェクトに追加します。
Vue.component('product', {
props: {
premium: {
type: Boolean,
required: true
}
},
// , ,
})
これは、Vueの組み込み機能を使用して、コンポーネントに渡されたパラメーターを検証することに注意してください。つまり、我々は、入力パラメータの種類は何を示し
premiumているBooleanと、このパラメータが設定することによって、必要とされるものrequiredにtrue。
次に、オブジェクトに渡されたパラメーターを表示するテンプレートに変更を加えましょう。
premiumページにプロパティ値を表示することで、調査しているメカニズムが正しく機能していることを確認します。
<p>User is premium: {{ premium }}</p>
これまでのところ、すべてが順調に進んでいます。コンポーネント
productは、操作に必要なtypeパラメーターを受け取ることを認識していますBoolean。関連データを表示する場所を用意しました。
ただし、パラメータはまだ
premiumコンポーネントに渡されていません。これは、入力パラメーター、特にを送信できるコンポーネントにつながる「行」に類似したカスタム属性を使用して行うことができますpremium。
のコードを変更しましょう
index.html:
<div id="app">
<product :premium="premium"></product>
</div>
ページを更新しましょう。

コンポーネントに渡されたデータの出力
入力パラメーターがコンポーネントに渡されるようになりました。私たちが今やったことについて正確に話しましょう。
コンポーネントに入力パラメータ、つまり「カスタム属性」を渡します
premium。コロン構造を使用してこのカスタム属性を、premiumVueインスタンスデータに格納されているプロパティにバインドします。
これで、ルートVueインスタンスを
premium子コンポーネントに渡すことができますproduct。属性はpremiumVueインスタンスデータのプロパティにバインドされているため、現在の値premiumは常にコンポーネントに渡されますproduct。
上の図、つまり碑文は
User is premium: true、すべてが正しく行われたことを証明しています。
これで、調査中のデータ転送メカニズムが期待どおりに機能していることを確認しました。Vue開発者ツールを調べると、コンポーネントに値を格納
Productする入力パラメーターがあるpremiumことがわかりますtrue。

コンポーネントの入力パラメータ
ユーザーがプレミアムアカウントを持っているかどうかに関するデータがコンポーネントに入力されたので、このデータを使用して、ページに送料情報を表示しましょう。パラメータが
premium値trueに設定されている場合、ユーザーは送料無料の資格があることを忘れないでください。新しい計算プロパティshippingを作成し、その中でパラメータを使用してみましょうpremium:
shipping() {
if (this.premium) {
return "Free";
} else {
return 2.99
}
}
パラメータに
this.premium格納されている場合true、計算されたプロパティshippingはを返しFreeます。それ以外の場合はを返し2.99ます。
コンポーネントテンプレートからパラメータ値の出力コードを削除しましょう
premium。これで、<p>Shipping: {{ shipping }}</p>今日開始したコードに存在していた要素が、送料に関する情報を表示できるようになります。

プレミアムユーザーは、コンポーネントが値に設定された入力パラメーターを送信されるため、ページに無料配信
テキスト
Shipping: Freeが表示されpremiumますtrue。
素晴らしい!これで、親エンティティから子にデータを転送する方法を学習し、コンポーネントでこのデータを使用して商品の配送コストを管理できるようになりました。
ちなみに、子コンポーネントの入力パラメータは変更しないでください。
ワークショップ
product-details入力パラメータdetailsを使用し、次のコードを使用して以前に形成された製品カードの一部のレンダリングを担当
する新しいコンポーネントを作成します。
<ul>
<li v-for="detail in details">{{ detail }}</li>
</ul>
これは、この問題を解決するために使用できるテンプレートです。
これが問題の解決策です。
結果
今日は、Vueコンポーネントの最初の紹介でした。これがあなたが学んだことです:
- コンポーネントは、カスタム要素として表示されるコードのブロックです。
- コンポーネントは、アプリケーションを再利用可能な部分に分割することにより、アプリケーションの管理を容易にします。これらには、アプリケーションの対応する部分のビジュアルコンポーネントと機能の説明が含まれています。
- コンポーネントデータは
data()、オプション付きのオブジェクトのメソッドによって表されます。 - 入力パラメータ(
props)は、親エンティティから子エンティティにデータを渡すために使用されます。 - コンポーネントが取る入力パラメータの要件を説明できます。
- .
- .
- Vue .
Vue開発者ツールを使用していますか?
→初心者向けVue.jsレッスン1:Vueインスタンス
→初心者向けVue.js、レッスン2:属性バインディング
→初心者向けVue.js、レッスン3:条件付きレンダリング
→初心者向けVue.js、レッスン4:レンダリングリスト
→ Vue .js初心者向けレッスン5:イベント処理
→ Vue.js初心者向けレッスン6:クラスとスタイルのバインド
→ Vue.js初心者向けレッスン7:計算されたプロパティ
→ Vue.js初心者向けレッスン8:コンポーネント
