Vue コンポーネントの 3 つの要素
1. props パラメータ
2. スロットカスタムスロット
3. イベントカスタムイベント
基本コンポーネントの開発
テンプレート、スクリプト、スタイルを含む .vue ファイルを作成します。
<template>
<div class="headComponent">
{
{ msg }}
</div>
</template>
<script>
export default {
props:['data','type'],
inheritAttrs: false,
data(){
return{
msg:'',
}
}
}
</script>
<style scoped>
</style>
ここまでで基本的なコンポーネントが完成しましたが、このコンポーネントを利用するには別のjsファイルに導入して登録する必要があります。
import Head from '../components/headComponent.vue'
共通コンポーネントをカプセル化するにはどうすればよいですか?
- まず、src ディレクトリに新しい Components フォルダーを作成します。
- パッケージ化される新しく作成されたコンポーネントはサブフォルダーと呼ばれます
- サブフォルダーの下に新しいindex.vueファイルを作成し、カプセル化するパブリックコンポーネントを保存します。
- 最後に、Components フォルダーの下に新しいindex.js ファイルを作成します。
- そしてパブリックコンポーネントをグローバルに登録します
import pageTools from './pageTools/index'
export default {
install(Vue) {
Vue.component('pageTools', pageTools)
}
}
このようにして、コンポーネントをインポートせずに、共通コンポーネントを他のコンポーネントで使用できます。
< pageTools></ pageTools>
コンポーネント間のデータ転送
* 親子コンポーネント通信
サブアセンブリ:
親コンポーネント:
1. 親コンポーネントが子コンポーネントにデータを渡します。
親コンポーネントは属性の形式で子コンポーネントにデータを渡し、子コンポーネントは props を使用してデータを受け取ります。ただし、共通コンポーネントのアプリケーション シナリオはより複雑です。props によって渡されるパラメータにいくつかの検証ルールを追加する必要があります。
props: {
propA: Number, // 基础类型检测 (`null` 意思是任何类型都可以)
propB: [String, Number], // 多种类型
propC: { // 必传且是字符串
type: String,
required: true
},
propD: { // 数字,有默认值
type: Number,
default: 100
},
propE: { // 数组/对象的默认值应当由一个工厂函数返回
type: Object,
default: function () {
return { message: 'hello' }
}
},
propF: { // 自定义验证函数
validator: function (value) {
return value > 10
}
}
}
単一項目のデータ フローの問題により、親コンポーネントから子コンポーネントに渡されるデータは直接変更しないでください。親コンポーネント内のデータも変更され、このデータも変更されると問題が発生するためです。他のコンポーネントに渡されます。Vue2.5 は props 用に最適化されており、この問題はなくなりました。そのような操作が必要な場合は、次のように記述できます。
let copyData = JSON.parse(JSON.stringify(this.data))
let myData = this.data とだけ書いてみてはいかがでしょうか? 直接割り当てのため、これは同じメモリ アドレスを指すオブジェクトと配列の浅いコピーにすぎず、一方を変更すると他方も変更されます。ただし、JSON を逆変換すると、相互に影響を及ぼさないディープコピーが実現されます。
2. 子コンポーネントは親コンポーネントにデータを渡します。
子コンポーネントは親コンポーネントにデータを渡します。親コンポーネントのメソッドをトリガーし、パラメータ データを親コンポーネントに渡します。
handleSubmit(data){
this.$emit('submitToParent', data)
}
親コンポーネントは、子コンポーネントから渡されたデータをどのように取得するのでしょうか?
<header @submitToParent="parentSubmit"></header>
methods: {
parentSubmit(data){
// 父组件的业务逻辑
}
}
3. 子コンポーネントが親コンポーネントのデータを変更する
親要素のデータを子コンポーネントに渡すときは、非基本型、つまりオブジェクトまたは配列を渡す必要があり、子コンポーネントはオブジェクト内のプロパティにアクセスしてデータを操作します。オブジェクトと配列は参照によって渡され、子コンポーネントで変更され、次のように親コンポーネントも同期的に変更されます。
// 父组件要props传递给子组件的数据
data:{
info:'父组件信息'
}
// 子组件
<template id="tpl">
<div>
<button @click="change">change</button>
<p>{
{data.info}}</p>
</div>
</template>
... 省略部分无关代码 ...
props:['data'],
methods:{
change(){
this.data.info = 'change info'
}
}
子コンポーネントが変更ボタンをクリックしてデータを変更すると、親コンポーネントも同期して変更されます。
4. スロットを使用する
汎用コンポーネントは多くの場合、すべてのアプリケーション シナリオに適しているわけではないため、コンポーネントをカプセル化するときにコンポーネントの機能の 80% だけを完了する必要があり、残りの 20% はソルトを通じて親コンポーネントによって解決されます。たとえば、パブリック コンポーネントには 2 つのボタンがあり、1 つは「追加」、もう 1 つは「削除」ですが、このコンポーネントを別のシーンで使用する場合、2 つのボタンは「表示」と「変更"。そのため、コンポーネントをカプセル化する際にはボタンを直接記述するのではなく、プレースホルダである適当な位置にスロットを配置し、あらかじめボタン設定の位置を確保しておき、親コンポーネントのボタンに記述するようにします。 。
サブアセンブリ:
<div class="child-btn">
<!-- 具名插槽 -->
<slot name="button"></slot>
<!-- 匿名插槽(每个组件只能有一个) -->
<slot><slot>
</div>
親コンポーネント:
<child>
<!-- 对应子组件中button的插槽 -->
<button slot="button">slot按钮</button>
</child>
共通コンポーネントを開発する場合、独立性の高いコンポーネントでない限り、スロットを追加するのが最善です。さらに、開発プロセス中に、サブコンポーネントに新しいコンテンツを追加する必要があることがよくありますが、このとき、サブコンポーネント内に 1 つ以上のソケットを残しておき、このサブコンポーネントを呼び出すときにコンテンツを追加すると、追加されたコンテンツが配布されます。スロット内の対応するものに:
サブアセンブリ:
<template>
<div class="headComponent">
<h3>这是一个头部组件</h3>
<slot></slot>
<slot name="s1"></slot>
<slot name="s2"></slot>
</div>
</template>
親コンポーネント:
<head-component>
<h2>不具名插槽</h2>
<h2 slot="s1">这里对应的是s1插口</h2>
<h2 slot="s2">这里对应的是s2插口</h2>
</head-component>
スロットは、子コンポーネントで変数を定義し、親コンポーネントでレンダリング方法をカスタマイズするためのスコープとして使用することもできます。(これはプロジェクト内でより多く使用され、vue+elementUI で ajax によって取得されたデータは、テーブル、および多くの場合、データの一部は直接表示されず、追加の処理が必要です)
サブアセンブリ:
<template>
<div class="headComponent">
<h3>这是一个头部组件</h3>
<slot name="head" v-for="head in heads" :text="head.text"></slot>
</div>
</template>
親コンポーネント:
<head-component>
<template slot="head" scope="props">
<li> {
{ props.text }} </li>
</template>
</head-component>
上記の例では、まず子コンポーネントにスロットを追加し、子コンポーネントで配列変数 heads を定義してから、スコープ テンプレートを使用して親コンポーネントにコンテンツを追加します。スコープは固有のプロパティであり、その値は次のとおりです。一時変数 props 。props は親コンポーネントから子コンポーネントに渡されるパラメータ head を受け取ります。
************************************************* ***********************************
スロットの使用方法:
スロットとは何ですか?
- スロット(Slot)はVueが提唱した概念で、その名のとおり、搭載されているコンテンツを指定の位置に挿入することを決定するために使用され、テンプレートをブロックに分割し、モジュール性を持たせ、再利用性を高めています。
- スロットを表示するかどうかおよび表示方法は親コンポーネントによって制御され、スロットが表示される場所は子コンポーネントによって制御されます。
- 親コンポーネントには構造があり、子コンポーネントはスロットを使用してその場所を占めます。
- スコープ スロットは、子から親にパラメータを渡す方法であり、通常のスロットが親内の子データにアクセスできないという問題を解決します。
スロットの使い方は?
デフォルトのスロット
親コンポーネント
<template>
<div>
我是父组件
<slotOne1>
<p style="color:red">我是父组件插槽内容</p>
</slotOne1>
</div>
</template>
親コンポーネントが参照する子コンポーネントに表示したい内容を記述します(ラベルの有無は問わない)
サブコンポーネント (slotOne1)
<template>
<div class="slotOne1">
<div>我是slotOne1组件</div>
<slot></slot>
</div>
</template>
子コンポーネントにスロットを記述します。スロットが配置される場所は、親コンポーネントによって表示されるコンテンツです。
- もちろん、親コンポーネントが参照する子コンポーネント内に他のコンポーネントを記述することもできます。
親コンポーネント
<template>
<div>
我是父组件
<slotOne1>
<p style="color:red">我是父组件插槽内容</p>
<slot-one2></slot-one2>
</slotOne1>
</div>
</template>
サブコンポーネント (slotOne2)
<template>
<div class="slotOne2">
我是slotOne2组件
</div>
</template>
名前付きスロット
サブアセンブリ
<テンプレート> <div class="slottwo"> <div>slottwo</div> <slot name="header" ></slot> <slot></slot> <slot name="footer" ></slot> </div> </template>
サブコンポーネントには 3 つのスロット タグが定義されており、そのうちの 2 つはそれぞれ name 属性のヘッダーとフッターとともに追加されます。
親コンポーネント
<template> <div> 私は親コンポーネントです <slot-two> <p>ラララ、ラララ、私は新聞販売のちょっとした専門家です</p> <template slot="header"> <p>私は header という名前のスロットです</p> </template> <p slot="footer">私は footer という名前のスロットです</p> </slot-two> </div> </template>
親コンポーネントでテンプレートを使用し、子コンポーネントでコンテンツの実際の位置を指定するために対応するスロット値を記述します(もちろん、テンプレートに記述する必要はありません)。対応する値のない他のコンテンツは、名前を追加せずに子コンポーネントに配置する 属性のスロットに
スロットのデフォルトの内容
親コンポーネント
<template>
<div>
我是父组件
<slot-two></slot-two>
</div>
</template>
サブアセンブリ
<template>
<div class="slottwo">
<slot>我不是卖报的小行家</slot>
</div>
</template>
子コンポーネントのスロットタグにコンテンツを書き込むことができます。親コンポーネントがコンテンツを書き込まない場合は、子コンポーネントのデフォルトのコンテンツが表示されます。親コンポーネントがコンテンツを書き込むと、子コンポーネントのデフォルトのコンテンツが置き換えられます。 。
コンパイル範囲
親コンポーネント
<template>
<div>
我是父组件
<slot-two>
<p>{
{name}}</p>
</slot-two>
</div>
</template>
<script>
export default {
data () {
return {
name: 'Jack'
}
}
}
</script>
サブアセンブリ
<template>
<div class="slottwo">
<slot></slot>
</div>
</template>
スコープ付きスロット
- スコープ スロットは、子から親にパラメータを渡す方法であり、通常のスロットが親内の子データにアクセスできないという問題を解決します。
サブアセンブリ
<template> <div> 私はスコープ付きスロットのサブコンポーネントです <slot :data="user" ></slot> </div> </template> <script> export default { name: 'slotthree', data ( ) { return { ユーザー: [ {名前: 'ジャック', 性別: '男の子'}, {名前: 'ジョーン', 性別: '女の子'}, { 名前: 'トム', 性別: '男の子'} ] } } </script>
子コンポーネントのスロット ラベルに必要な値をバインドします。
親コンポーネント
<template> <div> 我是作用域插槽 <slot-three> <template slot-scope="user" > <div v-for="(item,index) in user.data " :key="index" > { {item}} </div> </template> </slot-three> </div> </template>
親コンポーネントのslot-scope属性を使用します。user.dataは子コンポーネントから渡される値です。
包括的、props 属性を使用して値を渡し、スコープ スロット
親コンポーネント:
<template> <div> <p>vue の高特性</p> <hr> <ScopedSlotDemo :url="website.url"> <template slot-scope="slotProps" > { { slotProps.slotData .title}} < /template> </ScopedSlotDemo> </div> </template> <script> import ScopedSlotDemo from './ScopedSlotDemo' export default { data() { return { name:'小米', website: { url:'http:/ /imooc.com/'、 タイトル: 'imooc'、 サブタイトル: 「プログラマーのドリームワークス」 }, }; }、 コンポーネント:{ ScopedSlotDemo } }; </script> <stylescoped lang="css"> </style>
サブアセンブリ
<template> <a :href="url"> <slot :slotData="website1" > { {website1.subTitle}} <!-- デフォルト値は subTitle を表示します。つまり、親コンポーネントがコンテンツを渡さない場合 - -> </slot > </a> </template> <script> デフォルトのエクスポート { props: ['url'], data() { return { website1: { url: 'http://wangEditor.com/', title: 'wangEditor' 、 subTitle: '軽量リッチ テキスト エディター' } } } } </script>