Vue.js 組件通信主要通過以下幾種方式來實現:
Props(屬性)
- 方向:父組件到子組件
- 用途:父組件通過屬性向子組件傳遞數據。
- 特性:
- 只讀:默認情況下,子組件不能改變props的值。
- 驗證:可以通過props選項定義驗證規則。
- 動態:props的值可以隨父組件狀態的變化而變化。
父組件(Parent.vue)
<template><div><ChildComponent :message="parentMessage" /></div>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {parentMessage: 'Hello from Parent'};}
};
</script>
子組件(ChildComponent.vue)
<template><div><p>{{ message }}</p></div>
</template><script>
export default {props: {message: String}
};
</script>
$emit(事件)
- 方向:子組件到父組件
- 用途:子組件通過觸發自定義事件來通知父組件。
- 特性:
- 傳遞數據:事件可以攜帶數據。
- 多個事件:子組件可以觸發多個不同的事件。
子組件(ChildComponent.vue)
<template><button @click="notifyParent">Notify Parent</button>
</template><script>
export default {methods: {notifyParent() {this.$emit('child-event', 'Hello from Child');}}
};
</script>
父組件(Parent.vue)
<template><ChildComponent @child-event="handleChildEvent" />
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},methods: {handleChildEvent(data) {console.log('Received data from child:', data);}}
};
</script>
Vuex
- 全局狀態管理
- 用途:用于管理整個應用的狀態,任何組件都可以訪問。
- 特性:
- State:存儲全局狀態。
- Mutations:唯一改變state的方式,同步操作。
- Actions:用于異步操作,可以派發mutations。
- Getters:計算屬性,基于state創建緩存的屬性。
- Modules:大型應用中可以分割狀態管理模塊。
首先,設置 Vuex Store:
store.js
import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex);export default new Vuex.Store({state: {sharedCounter: 0},mutations: {increment(state) {state.sharedCounter++;}},actions: {incrementAsync({ commit }) {setTimeout(() => {commit('increment');}, 1000);}},getters: {getCounter: state => state.sharedCounter}
});
主應用(main.js)
確保應用使用了 Vuex Store
:
import Vue from 'vue';
import App from './App.vue';
import store from './store';new Vue({store,render: h => h(App)
}).$mount('#app');
父/子組件使用 Vuex
可以在任何組件中通過 this.$store
訪問 Vuex Store
。
ComponentUsingVuex.vue
<template><div><p>Counter: {{ counter }}</p><button @click="increment">Increment</button><button @click="incrementAsync">Increment Async</button></div>
</template><script>
export default {computed: {counter() {return this.$store.getters.getCounter;}},methods: {increment() {this.$store.commit('increment');},incrementAsync() {this.$store.dispatch('incrementAsync');}}
};
</script>
Provide/Inject
- 跨級通信
- 用途:允許祖先組件提供數據,后代組件注入數據,無需依賴父組件層級。
- 特性:
- 不受組件層次限制,但可能導致代碼耦合度增加。
- 不推薦在常規組件通信中廣泛使用,更適合庫或框架級別的數據傳遞。
祖先組件(AncestorComponent.vue)
<template><div><ChildComponent /></div>
</template><script>
export default {provide() {return {ancestorValue: 'Value from Ancestor'};}
};
</script>
后代組件(DescendantComponent.vue)
<template><div><p>Value from Ancestor: {{ injectedValue }}</p></div>
</template><script>
export default {inject: ['ancestorValue'],mounted() {console.log('Injected value:', this.injectedValue);}
};
</script>
Ref 和 v-model
- 直接引用
- 用途:父組件直接引用子組件實例,或雙向數據綁定。
- 特性:
- Refs:用于獲取子組件實例或DOM元素,進行直接操作。
- v-model:用于雙向數據綁定,常見于表單元素,也可以應用于自定義組件。
父組件(ParentComponent.vue)
<template><ChildComponent ref="childRef" v-model="parentValue" /><button @click="logChildRef">Log Child Ref</button>
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},data() {return {parentValue: 'Initial Value'};},methods: {logChildRef() {console.log(this.$refs.childRef);}}
};
</script>
子組件(ChildComponent.vue)
<template><input :value="value" @input="$emit('input', $event.target.value)" />
</template><script>
export default {props: ['value']
};
</script>
Custom Events(自定義事件)
- 事件通信
- 用途:自定義事件允許組件間非標準的通信。
- 特性:
- 可以在任何組件之間觸發和監聽。
- 適用于特定的交互或組件間的復雜通信。
子組件(ChildComponent.vue)
<template><button @click="customEvent">Send Custom Event</button>
</template><script>
export default {methods: {customEvent() {this.$emit('custom-event', 'Data to send');}}
};
</script>
父組件(ParentComponent.vue)
<template><ChildComponent @custom-event="handleCustomEvent" />
</template><script>
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},methods: {handleCustomEvent(data) {console.log('Received custom event data:', data);}}
};
</script>
Slots(插槽)
- 內容分發
- 用途:允許父組件的內容插入到子組件的特定位置。
- 特性:
- 默認插槽:子組件的默認內容區域。
- 具名插槽:子組件可以定義多個插槽,父組件指定插入內容的位置。
- 作用域插槽:父組件可以訪問子組件的數據來決定插槽內容。
父組件(ParentComponent.vue)
<template><WrapperComponent><h1 slot="header">Custom Header</h1><p slot="body">Custom Body Content</p></WrapperComponent>
</template><script>
import WrapperComponent from './WrapperComponent.vue';export default {components: {WrapperComponent}
};
</script>
WrapperComponent.vue
<template><div><slot name="header"></slot><div class="content"><slot name="body"></slot></div></div>
</template>
Composition API(組合API)
- 新功能
- 用途:Vue 3引入的新特性,允許在組件內更好地組織邏輯和數據。
- 特性:
setup()
函數:在組件生命周期開始時運行,可以訪問props和觸發生命周期鉤子。ref
和reactive
:用于響應式數據管理。provide
和inject
:在組合API中也有相應的實現,更靈活地進行跨組件數據傳遞。
父組件(ParentComponent.vue)
<template><ChildComponent :count="count" @updateCount="updateCount" />
</template><script>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';export default {components: {ChildComponent},setup() {const count = ref(0);function updateCount(newCount) {count.value = newCount;}onMounted(() => {console.log('Initial count:', count.value);});return {count,updateCount};}
};
</script>
子組件(ChildComponent.vue)
<template><button @click="increment">Increment</button>
</template><script>
import { ref, emit } from 'vue';export default {props: ['count'],setup(props) {const count = ref(props.count);function increment() {count.value++;emit('updateCount', count.value);}return {count,increment};}
};
</script>
2500G計算機入門到高級架構師開發資料超級大禮包免費送!