文章目录
-
- 父子组件通讯(通过props和$emit)
- 兄弟组件通讯(使用事件总线):
- 跨级组件通讯(使用provide/inject):
- 使用Vuex状态管理:
- 使用$refs引用组件:
父子组件通讯(通过props和$emit)
父组件可以通过props将数据传递给子组件,子组件可以通过$emit触发事件将数据传递回父组件。
javascript
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent :message="parentMessage" @childEvent="handleChildEvent" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
data() {
return {
parentMessage: 'Hello from parent',
};
},
components: {
ChildComponent,
},
methods: {
handleChildEvent(data) {
console.log('Data received from child:', data);
},
},
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<p>{{ message }}</p>
<button @click="emitEvent">Send Event</button>
</div>
</template>
<script>
export default {
props: ['message'],
methods: {
emitEvent() {
this.$emit('childEvent', 'Data from child');
},
},
};
</script>
兄弟组件通讯(使用事件总线):
可以通过共享一个父组件中的数据或使用事件总线(Event Bus)来实现兄弟组件之间的通讯
javascript
// EventBus.js
import Vue from 'vue';
export default new Vue();
<!-- ComponentA.vue -->
<template>
<div>
<input type="text" v-model="message" />
<button @click="sendMessage">Send Message</button>
</div>
</template>
<script>
import EventBus from './EventBus.js';
export default {
data() {
return {
message: '',
};
},
methods: {
sendMessage() {
EventBus.$emit('messageEvent', this.message);
},
},
};
</script>
<!-- ComponentB.vue -->
<template>
<div>
<p>{{ receivedMessage }}</p>
</div>
</template>
<script>
import EventBus from './EventBus.js';
export default {
data() {
return {
receivedMessage: '',
};
},
mounted() {
EventBus.$on('messageEvent', (message) => {
this.receivedMessage = message;
});
},
};
</script>
跨级组件通讯(使用provide/inject)
可以使用provide/inject来在祖先组件中提供数据,并在后代组件中注入数据。
javascript
<!-- GrandparentComponent.vue -->
<template>
<div>
<ParentComponent>
<ChildComponent />
</ParentComponent>
</div>
</template>
<script>
import { provide } from 'vue';
export default {
setup() {
const sharedData = 'Shared Data';
provide('sharedData', sharedData);
return {};
},
};
</script>
<!-- ParentComponent.vue -->
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
setup() {
return {};
},
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<p>{{ injectedData }}</p>
</div>
</template>
<script>
import { inject } from 'vue';
export default {
setup() {
const injectedData = inject('sharedData');
return {
injectedData,
};
},
};
</script>
使用Vuex状态管理
Vuex是Vue官方提供的状态管理库,可以用于在不同组件之间共享状态。
首先,需要安装和配置Vuex。然后,可以使用store中的state、mutations、actions等来修改和获取共享状态。
javascript
// store.js
import { createStore } from 'vuex';
const store = createStore({
state() {
return {
message: '',
};
},
mutations: {
setMessage(state, message) {
state.message = message;
},
},
});
export default store;
<!-- ComponentA.vue -->
<template>
<div>
<input type="text" v-model="message" />
<button @click="updateMessage">Update Message</button>
</div>
</template>
<script>
import { useStore } from 'vuex';
export default {
data() {
return {
message: '',
};
},
methods: {
updateMessage() {
const store = useStore();
store.commit('setMessage', this.message);
},
},
};
</script>
<!-- ComponentB.vue -->
<template>
<div>
<p>{{ receivedMessage }}</p>
</div>
</template>
<script>
import { computed } from 'vue';
import { useStore } from 'vuex';
export default {
setup() {
const store = useStore();
const receivedMessage = computed(() => {
return store.state.message;
});
return {
receivedMessage,
};
},
};
</script>
使用$refs引用组件
每个Vue组件都有一个唯一的ref属性,可以用于在父组件中引用子组件的实例,然后通过实例直接调用子组件的方法或访问数据。
javascript
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent ref="child" />
<button @click="callChildMethod">Call Child Method</button>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent,
},
methods: {
callChildMethod() {
this.$refs.child.childMethod();
},
},
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<p>{{ childData }}</p>
</div>
</template>
<script>
export default {
data() {
return {
childData: 'Data from child',
};
},
methods: {
childMethod() {
console.log('Child method called');
},
},
};
</script>