vue基础(八)
在 Vue 中,组件之间的传值方式主要包括以下几种情况:
1. 父组件向子组件传值(props
)
父组件通过 props
传递数据给子组件:
<!-- Parent.vue -->
<template>
<ChildComponent :msg="message" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
message: 'Hello from Parent!'
};
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<p>Received message: {{ msg }}</p>
</template>
<script>
export default {
props: {
msg: String
}
};
</script>
2. 子组件向父组件传值($emit
)
子组件通过 this.$emit
触发事件,父组件监听事件并获取值:
<!-- Parent.vue -->
<template>
<ChildComponent @update-message="handleMessage" />
<p>Message from Child: {{ receivedMessage }}</p>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
receivedMessage: ''
};
},
methods: {
handleMessage(msg) {
this.receivedMessage = msg;
}
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<button @click="sendMessage">Send to Parent</button>
</template>
<script>
export default {
methods: {
sendMessage() {
this.$emit('update-message', 'Hello from Child!');
}
}
};
</script>
3. 兄弟组件传值(Event Bus
或 Pinia/Vuex
)
兄弟组件需要一个中间桥梁,比如 Event Bus
(Vue 3 不推荐)或 Pinia
(推荐):
// eventBus.js (Vue 2 可用,Vue 3 推荐使用 Pinia)
import Vue from 'vue';
export const EventBus = new Vue();
在 BrotherA.vue
发送数据:
<template>
<button @click="sendMessage">Send to BrotherB</button>
</template>
<script>
import { EventBus } from './eventBus.js';
export default {
methods: {
sendMessage() {
EventBus.$emit('message', 'Hello from BrotherA!');
}
}
};
</script>
在 BrotherB.vue
接收数据:
<template>
<p>{{ receivedMessage }}</p>
</template>
<script>
import { EventBus } from './eventBus.js';
export default {
data() {
return { receivedMessage: '' };
},
created() {
EventBus.$on('message', msg => {
this.receivedMessage = msg;
});
}
};
</script>
4. ref
方式(获取子组件实例)
父组件可以通过 ref
获取子组件实例并访问其方法或数据:
<!-- Parent.vue -->
<template>
<ChildComponent ref="childRef" />
<button @click="callChildMethod">Call Child Method</button>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
methods: {
callChildMethod() {
this.$refs.childRef.childMethod();
}
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<p>Child Component</p>
</template>
<script>
export default {
methods: {
childMethod() {
console.log('Child method called!');
}
}
};
</script>
5. provide
和 inject
(适用于祖孙组件)
适用于跨层级组件通信:
<!-- GrandParent.vue -->
<template>
<Parent />
</template>
<script>
import Parent from './Parent.vue';
export default {
components: { Parent },
provide() {
return { sharedMessage: 'Hello from GrandParent!' };
}
};
</script>
<!-- Parent.vue -->
<template>
<Child />
</template>
<script>
import Child from './Child.vue';
export default {
components: { Child }
};
</script>
<!-- Child.vue -->
<template>
<p>{{ sharedMessage }}</p>
</template>
<script>
export default {
inject: ['sharedMessage']
};
</script>
6. Vuex 或 Pinia(全局状态管理)
适用于复杂状态管理,如 Vuex(Vue 2)或 Pinia(Vue 3):
// store.js (使用 Pinia)
import { defineStore } from 'pinia';
export const useMainStore = defineStore('main', {
state: () => ({
message: 'Hello from Store'
}),
actions: {
setMessage(newMsg) {
this.message = newMsg;
}
}
});
在 ComponentA.vue
更新数据:
<template>
<button @click="updateMessage">Update Message</button>
</template>
<script>
import { useMainStore } from './store.js';
export default {
setup() {
const store = useMainStore();
const updateMessage = () => store.setMessage('Updated Message!');
return { updateMessage };
}
};
</script>
在 ComponentB.vue
读取数据:
<template>
<p>{{ store.message }}</p>
</template>
<script>
import { useMainStore } from './store.js';
export default {
setup() {
const store = useMainStore();
return { store };
}
};
</script>