一、Vue 2
- 1、父组件向子组件传值,使用 props:可以通过在子组件上绑定 props,然后在父组件中通过 v-bind 绑定相应的数据来传递数据。
父组件中的代码:
import ChildComponent from './ChildComponent.vue';export default { components: { ChildComponent, }, data() { return { dataA: 'data from parent', }; },};子组件中的代码:
{{ propA }} export default { props: { propA: String, },};- 2、子组件向父组件传值,使用 $emit:可以通过在子组件中使用 $emit 触发自定义事件,并在父组件中使用 v-on 监听相应的事件来传递数据。
子组件中的代码:
export default { data() { return { dataB: 'data from child', }; }, methods: { sendDataToParent() { this.$emit('send-data', this.dataB); }, },};父组件中的代码:
import ChildComponent from './ChildComponent.vue';export default { components: { ChildComponent, }, methods: { receiveDataFromChild(dataB) { console.log(dataB); }, },};- 3、兄弟组件之间传值:可以通过使用一个共同的父组件,然后将需要共享的数据放在父组件的 data 中,再通过 props 将数据传递给各自的子组件。
父组件中的代码:
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', }; },};子组件 A 中的代码:
{{ propA }} export default { props: { propA: String, },};子组件 B 中的代码:
{{ propB }} export default { props: { propB: String, },};- 4、跨级组件传值,使用 provide 和 inject(该方法也可用于父子组件传值):provide 可以在祖先组件中定义一个值或者方法,然后在子孙组件中使用 inject 来注入这个值或者方法。
祖先组件中的代码:
import ChildA from './ChildA.vue';export default { components: { ChildA, }, provide() { return { sharedData: 'data from ancestor', }; },};子孙组件 A 中的代码:
{{ sharedData }} export default { inject: ['sharedData'],};- 5、使用全局事件总线:可以使用 Vue 的事件机制,通过在 Vue 实例上使用 $on 来监听事件,然后在其他组件中使用 $emit 触发相应的事件来传递数据。这种方式可以在任意组件之间传递数据。
在 main.js 中定义一个空的 Vue 实例作为事件总线:
import Vue from 'vue';export const bus = new Vue();
子组件 A 中的代码:
import { bus } from './main';export default { methods: { sendDataToSibling() { bus.$emit('send-data', 'data from child a'); }, },};子组件 B 中的代码:
{{ dataFromSibling }} import { bus } from './main';export default { data() { return { dataFromSibling: '', }; }, mounted() { bus.$on('send-data', (data) => { this.dataFromSibling = data; }); },};- 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 中的代码:
import { mapMutations } from 'vuex';export default { methods: { ...mapMutations(['updateDataC']), sendDataToSibling() { this.updateDataC('data from child a'); }, },};子组件 B 中的代码:
{{ dataC }} import { mapState } from 'vuex';export default { computed: { ...mapState(['dataC']), },};- 7、父子组件传值,使用
$attrs
和 $listeners
:
$attrs 是一个包含了父组件传递给子组件的所有属性的对象,可以在子组件中通过访问 $attrs
来获取这些属性。如果不希望某些属性传递到子组件中,可以在子组件中使用 v-bind="$attrs"
并指定排除的属性名称,或者在父组件中使用 .sync
修饰符,将属性绑定到子组件的一个名为 $attrs
的属性上。
$listeners 是一个包含了父组件传递给子组件的所有事件监听器的对象,可以在子组件中通过访问 $listeners
来获取这些事件监听器。如果需要在子组件中监听某个事件,可以使用 v-on="$listeners"
将所有的事件监听器绑定到子组件上。
$attrs 和 $listeners 是常用的两个特殊属性,它们可以用来向组件传递属性和事件监听器。假设我们有一个父组件和一个子组件,子组件需要接收父组件的一些属性和事件监听器,同时还需要把这些属性和事件传递给子组件的某个子元素。
父组件中的代码:
import ChildComponent from './ChildComponent.vue';export default { components: { ChildComponent }, data() { return { title: 'Hello World', }; }, methods: { handleClick() { console.log('Button Clicked'); }, },};子组件中的代码:
export default { inheritAttrs: false, props: { title: { type: String, default: '', }, }, mounted() { console.log(this.$attrs); console.log(this.$listeners); },};在子组件中,我们使用 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 中定义对应的属性名,可以获取到父组件传递过来的数据。
例如,父组件中的模板:
import ChildComponent from './ChildComponent.vue';export default { components: { ChildComponent }, data() { return { hello: 'Hello from parent!' }; }};
子组件中的模板:
{{ message }}export default { props: { message: String }};- 2、$emit
$emit 是一种在子组件中触发事件的方式,通过在子组件中使用 $emit
方法,可以向父组件发送数据。在父组件中,通过在子组件标签上使用 v-on
或 @
语法,可以监听子组件触发的事件,并获取子组件发送的数据。
例如,子组件中的模板:
export default { methods: { sendMessage() { this.$emit('message-sent', 'Hello from child!'); } }};
父组件中的模板:
import ChildComponent from './ChildComponent.vue';export default { components: { ChildComponent }, methods: { receiveMessage(message) { console.log(message); } }};
- 3、Provide/Inject
Provide/Inject 是一种在祖先组件和后代组件之间共享数据的方式。通过在祖先组件中使用 provide
方法提供数据,在后代组件中使用 inject
方法获取数据。
例如,祖先组件中的模板:
import ChildComponent from './ChildComponent.vue';export default { components: { ChildComponent }, provide() { return { message: 'Hello from ancestor!' }; }};
后代组件中的模板:
{{ message }}export default { inject: ['message']};- 4、$attrs 和 $listeners
$attrs 和 $listeners 是在 Vue 2 中引入的特性,但在 Vue 3 中也得到了支持。
例如,父组件中的模板:
import ChildComponent from './ChildComponent.vue';export default { components: { ChildComponent }, methods: { handleClick() { console.log('Clicked!'); } }};
子组件中的模板:
{{ message }}export default { props: { message: String }};- 5、provide/inject 与 props 的结合使用
在 Vue 3 中,provide 和 inject 可以与 props 结合使用,从而实现一种高级的数据传递方式。具体做法是,在祖先组件中使用 provide 方法提供数据,并在后代组件中使用 inject 方法获取数据;同时,在后代组件中,可以在 props 中声明和接收数据,从而实现数据的类型检查和默认值设定。
例如,祖先组件中的模板:
import ChildComponent from './ChildComponent.vue';export default { components: { ChildComponent }, provide() { return { message: 'Hello from ancestor!' }; }};
后代组件中的模板:
{{ message }}export default { inject: ['message'], props: { message: { type: String, default: 'Hello from default!' } }};在上面的例子中,子组件会首先从祖先组件中获取名为 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:
{{ message }} import { mapGetters, mapMutations } from 'vuex';export default { computed: { ...mapGetters(['getMessage']) }, methods: { ...mapMutations(['updateMessage']) }};在这个例子中,组件通过 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:
{{ message }} 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); }); }};在这个例子中,组件中的 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
声明:欢迎任何形式的转载,但请务必注明出处!!!