一、Vue 2
- 1、父組件向子組件傳值,使用 props:可以通過在子組件上系結 props,然后在父組件中通過 v-bind 系結相應的資料來傳遞資料,
父組件中的代碼:
<template>
<div>
<child-component :prop-a="dataA"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent,
},
data() {
return {
dataA: 'data from parent',
};
},
};
</script>
子組件中的代碼:
<template>
<div>
{{ propA }}
</div>
</template>
<script>
export default {
props: {
propA: String,
},
};
</script>
- 2、子組件向父組件傳值,使用 $emit:可以通過在子組件中使用 $emit 觸發自定義事件,并在父組件中使用 v-on 監聽相應的事件來傳遞資料,
子組件中的代碼:
<template>
<div>
<button @click="sendDataToParent">Send Data To Parent</button>
</div>
</template>
<script>
export default {
data() {
return {
dataB: 'data from child',
};
},
methods: {
sendDataToParent() {
this.$emit('send-data', this.dataB);
},
},
};
</script>
父組件中的代碼:
<template>
<div>
<child-component @send-data="https://www.cnblogs.com/yuzhihui/archive/2023/02/16/receiveDataFromChild"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent,
},
methods: {
receiveDataFromChild(dataB) {
console.log(dataB);
},
},
};
</script>
- 3、兄弟組件之間傳值:可以通過使用一個共同的父組件,然后將需要共享的資料放在父組件的 data 中,再通過 props 將資料傳遞給各自的子組件,
父組件中的代碼:
<template>
<div>
<child-a :prop-a="dataA"></child-a>
<child-b :prop-b="dataB"></child-b>
</div>
</template>
<script>
import ChildA from './ChildA.vue';
import ChildB from './ChildB.vue';
export default {
components: {
ChildA,
ChildB,
},
data() {
return {
dataA: 'data from parent to child a',
dataB: 'data from parent to child b',
};
},
};
</script>
子組件 A 中的代碼:
<template>
<div>
{{ propA }}
</div>
</template>
<script>
export default {
props: {
propA: String,
},
};
</script>
子組件 B 中的代碼:
<template>
<div>
{{ propB }}
</div>
</template>
<script>
export default {
props: {
propB: String,
},
};
</script>
- 4、跨級組件傳值,使用 provide 和 inject(該方法也可用于父子組件傳值):provide 可以在祖先組件中定義一個值或者方法,然后在子孫組件中使用 inject 來注入這個值或者方法,
祖先組件中的代碼:
<template>
<div>
<child-a></child-a>
</div>
</template>
<script>
import ChildA from './ChildA.vue';
export default {
components: {
ChildA,
},
provide() {
return {
sharedData: 'data from ancestor',
};
},
};
</script>
子孫組件 A 中的代碼:
<template>
<div>
{{ sharedData }}
</div>
</template>
<script>
export default {
inject: ['sharedData'],
};
</script>
- 5、使用全域事件總線:可以使用 Vue 的事件機制,通過在 Vue 實體上使用 $on 來監聽事件,然后在其他組件中使用 $emit 觸發相應的事件來傳遞資料,這種方式可以在任意組件之間傳遞資料,
在 main.js 中定義一個空的 Vue 實體作為事件總線:
import Vue from 'vue';
export const bus = new Vue();
子組件 A 中的代碼:
<template>
<div>
<button @click="sendDataToSibling">Send Data To Sibling</button>
</div>
</template>
<script>
import { bus } from './main';
export default {
methods: {
sendDataToSibling() {
bus.$emit('send-data', 'data from child a');
},
},
};
</script>
子組件 B 中的代碼:
<template>
<div>
{{ dataFromSibling }}
</div>
</template>
<script>
import { bus } from './main';
export default {
data() {
return {
dataFromSibling: '',
};
},
mounted() {
bus.$on('send-data', (data) => {
this.dataFromSibling = data;
});
},
};
</script>
- 6、使用 Vuex:當應用的資料狀態比較復雜或者需要在多個組件之間共享時,可以使用 Vuex,它是一個專為 Vue.js 應用程式開發的狀態管理模式,可以在任何組件中訪問和修改 Vuex 存盤的資料,通過 mutations 來修改狀態,通過 actions 來觸發 mutations,這種方式可以方便地在不同的組件中進行狀態管理和資料共享,
在 store.js 中定義一個 Vuex store:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
dataC: 'data from Vuex',
},
mutations: {
updateDataC(state, payload) {
state.dataC = payload;
},
},
});
export default store;
子組件 A 中的代碼:
<template>
<div>
<button @click="sendDataToSibling">Send Data To Sibling</button>
</div>
</template>
<script>
import { mapMutations } from 'vuex';
export default {
methods: {
...mapMutations(['updateDataC']),
sendDataToSibling() {
this.updateDataC('data from child a');
},
},
};
</script>
子組件 B 中的代碼:
<template>
<div>
{{ dataC }}
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['dataC']),
},
};
</script>
- 7、父子組件傳值,使用
$attrs和$listeners:
$attrs 是一個包含了父組件傳遞給子組件的所有屬性的物件,可以在子組件中通過訪問 $attrs 來獲取這些屬性,如果不希望某些屬性傳遞到子組件中,可以在子組件中使用 v-bind="$attrs" 并指定排除的屬性名稱,或者在父組件中使用 .sync 修飾符,將屬性系結到子組件的一個名為 $attrs 的屬性上,
$listeners 是一個包含了父組件傳遞給子組件的所有事件監聽器的物件,可以在子組件中通過訪問 $listeners 來獲取這些事件監聽器,如果需要在子組件中監聽某個事件,可以使用 v-on="$listeners" 將所有的事件監聽器系結到子組件上,
$attrs 和 $listeners 是常用的兩個特殊屬性,它們可以用來向組件傳遞屬性和事件監聽器,假設我們有一個父組件和一個子組件,子組件需要接收父組件的一些屬性和事件監聽器,同時還需要把這些屬性和事件傳遞給子組件的某個子元素,
父組件中的代碼:
<template>
<div>
<child-component :title="title" v-on:click="handleClick" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
title: 'Hello World',
};
},
methods: {
handleClick() {
console.log('Button Clicked');
},
},
};
</script>
子組件中的代碼:
<template>
<div>
<button @click="$emit('click')">Click me</button>
<div v-bind="$attrs">
<slot />
</div>
</div>
</template>
<script>
export default {
inheritAttrs: false,
props: {
title: {
type: String,
default: '',
},
},
mounted() {
console.log(this.$attrs);
console.log(this.$listeners);
},
};
</script>
在子組件中,我們使用 v-bind="$attrs" 把所有父組件傳遞過來的屬性系結到子元素上,同時,我們使用 $emit('click') 來觸發父組件傳遞過來的點擊事件,
在子組件 中,需要設定 inheritAttrs: false,來禁止自動將父組件傳遞的屬性系結到子組件的根元素上,這樣,我們就可以使用 v-bind="$attrs" 把所有屬性系結到子元素上,
在 mounted 鉤子中,我們可以通過 this.$attrs 和 this.$listeners 來分別訪問所有屬性和事件監聽器,這樣,我們就可以在子組件中使用這些屬性和事件了,
- 8、使用 $refs:可以使用 Vue 提供的 $refs 屬性來獲取組件實體,然后通過呼叫組件的方法來進行資料傳遞,這種方式不推薦使用,因為不易維護和除錯,
-
9、使用事件總線庫:可以使用 Vue.js 的第三方庫如 Event Bus、Tiny-Emmiter 等來傳遞資料,這些庫提供了一種方便、簡單的方式來在不同的組件之間進行事件傳遞,但是需要注意,使用第三方庫可能會增加專案的復雜性和維護成本,
二、Vue 3
- 1、Props
Props 是一種在組件之間傳遞資料的方式,通過在組件標簽上使用屬性系結,父組件可以向子組件傳遞資料,在子組件中,通過在 props 中定義對應的屬性名,可以獲取到父組件傳遞過來的資料,
例如,父組件中的模板:
<template>
<child-component :message="hello"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
hello: 'Hello from parent!'
};
}
};
</script>
子組件中的模板:
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
props: {
message: String
}
};
</script>
- 2、$emit
$emit 是一種在子組件中觸發事件的方式,通過在子組件中使用 $emit 方法,可以向父組件發送資料,在父組件中,通過在子組件標簽上使用 v-on 或 @ 語法,可以監聽子組件觸發的事件,并獲取子組件發送的資料,
例如,子組件中的模板:
<template>
<button @click="sendMessage">Send Message</button>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('message-sent', 'Hello from child!');
}
}
};
</script>
父組件中的模板:
<template>
<child-component @message-sent="receiveMessage"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
receiveMessage(message) {
console.log(message);
}
}
};
</script>
- 3、Provide/Inject
Provide/Inject 是一種在祖先組件和后代組件之間共享資料的方式,通過在祖先組件中使用 provide 方法提供資料,在后代組件中使用 inject 方法獲取資料,
例如,祖先組件中的模板:
<template>
<child-component></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
provide() {
return {
message: 'Hello from ancestor!'
};
}
};
</script>
后代組件中的模板:
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
inject: ['message']
};
</script>
- 4、$attrs 和 $listeners
$attrs 和 $listeners 是在 Vue 2 中引入的特性,但在 Vue 3 中也得到了支持,
例如,父組件中的模板:
<template>
<child-component message="Hello from parent!" @click="handleClick"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
handleClick() {
console.log('Clicked!');
}
}
};
</script>
子組件中的模板:
<template>
<div v-bind="$attrs" v-on="$listeners">{{ message }}</div>
</template>
<script>
export default {
props: {
message: String
}
};
</script>
- 5、provide/inject 與 props 的結合使用
在 Vue 3 中,provide 和 inject 可以與 props 結合使用,從而實作一種高級的資料傳遞方式,具體做法是,在祖先組件中使用 provide 方法提供資料,并在后代組件中使用 inject 方法獲取資料;同時,在后代組件中,可以在 props 中宣告和接收資料,從而實作資料的型別檢查和默認值設定,
例如,祖先組件中的模板:
<template>
<child-component></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
provide() {
return {
message: 'Hello from ancestor!'
};
}
};
</script>
后代組件中的模板:
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
inject: ['message'],
props: {
message: {
type: String,
default: 'Hello from default!'
}
}
};
</script>
在上面的例子中,子組件會首先從祖先組件中獲取名為 message 的資料,如果沒有提供,則使用默認值 Hello from default!,在子組件中,props 會覆寫 provide/inject,因此如果父組件和子組件都提供了同一個屬性,子組件中的 props 值會覆寫 provide/inject 中的值,
- 6、Vuex
Vuex 是一種專門用于管理應用程式狀態的庫,可以用于跨組件傳遞資料,在 Vuex 中,可以定義一個全域的狀態管理器,所有的組件都可以通過 getter 和 setter 方法訪問和修改這個狀態管理器中的資料,
例如,定義一個 Vuex store:
import { createStore } from 'vuex';
const store = createStore({
state: {
message: 'Hello from store!'
},
mutations: {
updateMessage(state, message) {
state.message = message;
}
},
getters: {
getMessage(state) {
return state.message;
}
}
});
export default store;
在組件中使用 Vuex:
<template>
<div>{{ message }}</div>
<button @click="updateMessage">Update message</button>
</template>
<script>
import { mapGetters, mapMutations } from 'vuex';
export default {
computed: {
...mapGetters(['getMessage'])
},
methods: {
...mapMutations(['updateMessage'])
}
};
</script>
在這個例子中,組件通過 mapGetters 方法將 Vuex store 中的 getMessage 方法映射為組件中的計算屬性,從而獲取 Vuex store 中的資料;同時,通過 mapMutations 方法將 Vuex store 中的 updateMessage 方法映射為組件中的方法,從而修改 Vuex store 中的資料,
- 7、EventBus
EventBus 是一種自定義事件總線,可以用于在任意組件之間傳遞資料,在 EventBus 中,可以定義一個全域的事件中心,所有的組件都可以通過 $on 和 $emit 方法監聽和觸發自定義事件,
例如,定義一個 EventBus:
import mitt from 'mitt';
const bus = mitt();
export default bus;
在組件中使用 EventBus:
<template>
<div>{{ message }}</div>
<button @click="updateMessage">Update message</button>
</template>
<script>
import bus from './event-bus';
export default {
data() {
return {
message: 'Hello from component!'
};
},
methods: {
updateMessage() {
this.message = 'New message!';
bus.emit('message-updated', this.message);
}
},
created() {
bus.on('message-updated', message => {
console.log(message);
});
}
};
</script>
在這個例子中,組件中的 updateMessage 方法通過 EventBus 的 emit 方法觸發了一個名為 message-updated 的自定義事件,并將修改后的訊息作為引數傳遞給事件處理函式;同時,在組件的 created 生命周期鉤子中,通過 EventBus 的 on 方法監聽名為 message-updated 的自定義事件,并在事件處理函式中列印接收到的訊息,
總之,Vue 3 中組件之間傳值的方式很多,可以根據具體的場景選擇最適合的方式,使用 props 和 $emit 可以實作父子組件之間的傳值,使用 provide 和 inject 可以實作祖先組件向后代組件的傳值,使用 Vuex 和 EventBus 可以實作任意組件之間的傳值,在選擇組件傳值方式時,還應該考慮資料的安全性、可維護性和性能等因素,
作者:yuzhihui
出處:https://www.cnblogs.com/yuzhihui/p/17125771.html
宣告:歡迎任何形式的轉載,但請務必注明出處!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/544137.html
標籤:其他
