基本的なルーティングコンポーネントの知識
props:親子コンポーネント間(配列、文字列)、子親コンポーネント間(関数)、兄弟コンポーネント間(データを親コンポーネントにマウント)の通信を実現します(読み取り専用)。
カスタムイベント:子親コンポーネント間の通信を可能にします。
グローバルイベントバス$BUS:任意のコンポーネント間の通信を可能にします(Vue 2で重要)。
pubsub:発行/購読パターンを使用して任意のコンポーネント間の通信を実現します(Vueプロジェクトではあまり使われませんが、Reactプロジェクトや微信小程序プロジェクトではよく使われます)。
Vuex:集中式ステート管理コンテナで、任意のコンポーネント間の通信を可能にします(欠点:データは永続化されません)。
ref:親コンポーネントから子コンポーネントのインスタンスVCを取得し、子コンポーネントのリアクティブなデータとメソッドにアクセスします。
slot:スロット(デフォルトスロット、名前付きスロット、スコープスロット)を使用して親子コンポーネント間の通信を実現します。
1. propsによるルーティングコンポーネント
基本的な知識:1. プロジェクトの実行:ターミナルで `npm run dev` を入力します。2. Vueファイルテンプレートの自動生成方法:ファイル -> 事前設定 -> ユーザースニペット -> vue.json を入力 -> コードを入力します。
{
"Vue Component Template": {
"prefix": "vue",
"body": [
"<template>",
" <div>",
" <!-- Component HTML goes here -->",
" </div>",
"</template>",
"",
"<script>",
"export default {",
" name: '$1',",
" data() {",
" return {",
" // component data",
" };",
" },",
" methods: {",
" // component methods",
" }",
"};",
"</script>",
"",
"<style scoped>",
"/* component CSS styles */",
"</style>"
],
"description": "Basic Vue component structure"
}
}
props: 親子コンポーネント間の通信を実現します。propsのデータは読み取り専用です!
1.1 親コンポーネントからのパラメータの受け渡し
親コンポーネント内でインポートを記述します:`import Child from './Child.vue';` div内に`<child></child>`を記述します。 コンポーネント間の通信は属性形式で行われます。
1. 親コンポーネントから子コンポーネントへの文字列の伝達:
<child info="私は曹操"></child>
2. 組み合わせAPI関数を使用して動的にデータを伝達します。
import { ref } from 'vue';
let money = ref(10000);
<child info="私は曹操" :money="money"></child>
前者のデータ伝達は固定的ですが、後者は柔軟です。
1.2 子コンポーネントでのデータ受信
1. オプションAPI書き方
// export default {
// props: ['info', 'money']
// };
<p>{{ info }}</p>
2. 組み合わせAPI書き方 setup
// definePropsはVue 3で提供されるメソッドで、インポート不要
let props = defineProps(['info', 'money']);
<p>{{ props.info }}</p>
<p>{{ $props.money }}</p>
<p>{{ info }}</p>
<p>{{ money }}</p>
プロキシオブジェクトの配列propsは変更できません。変更が必要な場合は、親コンポーネント内で変更します。
2. カスタムイベント
2.1 ネイティブDOMイベント
ユーザーがウェブページと対話する際のマウスクリックなどの方法があります。
<button @click="handler1(1, 2, 3, $event)">クリックして複数のパラメータを伝達</button> <Event1 @click="handler2"></Event1>
// サブコンポーネントのインポート
import Event1 from './Event1.vue';
const handler = (event) => {
console.log(event);
}
const handler1 = (a, b, c, $event) => {
console.log(a, b, c, $event);
}
const handler2 = () => {
console.log(123);
}
2.2 カスタムイベント
コンポーネント間の通信を実現し、子コンポーネントから親コンポーネントへパラメータを伝達します。
<Event2 @xxx="handler3" @click="handler4"></Event2>
// サブコンポーネントのインポート
import Event2 from './Event2.vue';
const handler3 = (param1, param2) => {
console.log(param1, param2);
}
const handler4 = (param1, param2) => {
console.log(param1, param2);
}
Event2.vue
<template>
<div class="child">
<p>私は子コンポーネント2です</p>
<button @click="handler">クリックしてカスタムイベントをトリガー</button>
<button @click="$emit('click', 'AK47', 'J20')">クリックしてカスタムイベントclickをトリガー</button>
</div>
</template>
<script setup lang="ts">
let $emit = defineEmits(['xxx']);
const handler = () => {
$emit('xxx', '東風ミサイル', '空母');
}
</script>
<style scoped>
.child {
width: 400px;
height: 200px;
background-color: pink;
}
</style>
3. グローバルイベントバス
グローバルイベントバスは任意のコンポーネント間の通信を可能にします。Vue 2ではVMとVCの関係からグローバルイベントバスを導出できますが、Vue 3ではVueコンストラクタがないため、mittプラグインを使用します。
例:兄弟コンポーネント間の通信
1. bus/index.tsを作成してbusオブジェクトをカプセル化します。
import mitt from "mitt"; const $bus = mitt(); export default $bus;
2. 兄弟コンポーネント2にイベントをバインドします。
<script setup lang="ts">
import $bus from '../../bus';
import { onMounted } from 'vue';
onMounted(() => {
$bus.on('car', (car) => {
console.log(car);
});
})
</script>
3. 兄弟コンポーネント1がイベントをトリガーします。
<template>
<div class="child2">
<h1>私は子コンポーネント2: 曹丕</h1>
<button @click="handler">クリックして兄弟に車を送る</button>
</div>
</template>
<script setup lang="ts">
import $bus from '@/bus';
const handler = () => {
$bus.emit('car', { car: "フェラーリ" });
}
</script>
<style scoped>
.child2 {
width: 300px;
height: 300px;
background-color: skyblue;
}
</style>
4. v-model
v-modelを使用して親子コンポーネント間のデータ同期を実現します。
子コンポーネント
<template>
<div class="child">
<h3>金額: {{ modelValue }}</h3>
<button @click="handler">親子コンポーネント間のデータ同期</button>
</div>
</template>
<script setup lang="ts">
let props = defineProps(['modelValue']);
let $emit = defineEmits(['update:modelValue']);
const handler = () => {
$emit('update:modelValue', props.modelValue + 1000);
}
</script>
<style scoped>
.child {
width: 600px;
height: 300px;
background-color: skyblue;
}
</style>
親コンポーネント
<template>
<div>
<h1>v-model: 金額: {{ money }}</h1>
<input type="text" v-model="info">
<hr>
<Child :modelValue="money" @update:modelValue="handler"></Child>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import Child from './Child.vue';
let info = ref('');
let money = ref(10000);
const handler = (num: any) => {
money.value = num;
}
</script>
<style scoped></style>
5. useAttrs
useAttrsを使用してコンポーネントの属性とイベントを取得します。
例:el-buttonコンポーネントを再ラッピングし、マウスを置くとテキストが表示されます。
<el-button type="primary" size="small" :icon="Edit"></el-button> <HintButton type="primary" size="small" :icon="Edit"></HintButton>
type="primary" size="small" :icon="Edit"はpropsとして扱われ、子コンポーネントが受け取ります。
// useAttrsを使用して属性とイベントを取得
import { useAttrs } from 'vue';
let $attrs = useAttrs();
console.log($attrs);
ビュー表示
<el-button :="$attrs"></el-button> <div :title="title"></div>
useAttrsはイベントも受け取ることができます。
6. ref と $parent
ref: 実際のDOMノードを取得し、子コンポーネントのインスタンスVCを取得します。
$parent: 子コンポーネント内で親コンポーネントのインスタンスを取得します。
例:親コンポーネントにボタンを設置し、親の金額を+10、子の金額を-10します。
<Son ref="son"></Son>
let son = ref();
子コンポーネントの具体的なデータにはアクセスできないため、子コンポーネント内でメソッドを公開します。
defineExpose({
money,
fly
});
子コンポーネントのインスタンスを取得し、データとメソッドを使用します。
const handler = () => {
money.value += 10;
son.value.money -= 10;
son.value.fly();
}
7. provide と inject
Vue 3はprovide(提供)とinject(注入)を提供し、隔世コンポーネント間のデータ伝達を可能にします。
provide('TOKEN', car);
孫コンポーネント(息子または孫でも使用可)
import { inject } from 'vue';
let car = inject('TOKEN');
const updateCar = () => {
car.value = '自転車';
}
孫コンポーネントは直接祖父コンポーネントから渡されたデータを変更できます。
8. PiniaのオプションAPI
Vue 2では通常、Vuex集中型ステート管理コンテナを使用して任意のコンポーネント間の通信を実現します。Vue 3ではPiniaを使用します。
Piniaの書き方は2種類あり、オプションAPIと組み合わせAPIがあります。
store/index.tsを作成して大規模なストアを作成します。
import { createPinia } from "pinia";
let store = createPinia();
export default store;
エントリーポイントmain.tsでストアをインポートします。
import store from './store'; app.use(store);
小さなストアstore/modules/info.tsを作成します。
import { defineStore } from "pinia";
let useInfoStore = defineStore("info", {
state: () => {
return {
count: 99,
arr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
},
actions: {
updateNum(a: number, b: number) {
this.count++;
}
},
getters: {
total() {
let result: any = this.arr.reduce((prev: number, next: number) => {
return prev + next;
}, 0);
return result;
}
}
});
export default useInfoStore;
倉庫データの更新方法:
<button @click="updateCount">クリックして倉庫データを更新</button>
const updateCount = () => {
infoStore.updateNum(66, 77);
}
gettersメソッドはデータを簡略化し、計算します。
getters: {
total() {
let result: any = this.arr.reduce((prev: number, next: number) => {
return prev + next;
}, 0);
return result;
}
}
reduce()メソッドの詳細については、以下のリンクを参照してください。
https://blog.csdn.net/w17624003437/article/details/125858710
9. Piniaの組み合わせAPI
Piniaの組み合わせAPIについても同様に適用できます。