在Vue.js中,以下是十种常见的组件间传值方式:
-
Props(父组件向子组件传值):使用props属性来向子组件传递数据。
-
Emit(子组件向父组件传值):子组件通过$emit方法触发自定义事件,父组件通过监听这些事件来接收子组件传递的值。
-
Provide/Inject(祖先组件向后代组件传值):使用provide选项在祖先级组件中提供数据,然后在后代组件中使用inject选项来接收这些数据。
-
Vuex(全局状态管理):使用Vuex来创建全局的store,组件通过dispatch触发action来改变状态,其他组件通过getters或订阅变化来获取状态。
-
$attrs/$listeners(透传属性和事件):通过设置inheritAttrs选项和$attrs/$listeners来在高层组件传递属性和事件给低层组件。
-
$parent 和 $children(父子组件之间的直接引用):通过parent属性可以直接访问父组件的实例,通过$children数组可以直接访问子组件的实例。
-
$refs(通过引用访问组件实例):通过ref属性可以为组件添加一个唯一的引用标识,在父组件中可以通过refs属性访问到子组件的实例。
-
EventBus(事件总线):创建一个Vue实例作为事件总线,组件通过这个实例的emit和on方法进行事件的发布和订阅,传递数据。
-
状态提升(兄弟组件之间传值):将需要共享的数据放到它们共同的父组件中,然后通过props和emit在父组件中传递数据。
-
URL参数(路由传参):使用路由的params、query、hash等方式,将数据通过URL传递给目标组件。
这些传值方式可以根据具体场景和需求选择合适的方式来实现组件之间的数据传递和交互。
一.props
父组件:
<template>
<child-component :propName="propValue"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
propValue: 'Value from parent component'
};
}
};
</script>
子组件:
<template>
<div>{{ propName }}</div>
</template>
<script>
export default {
props: ['propName']
};
</script>
二.Emit
子组件:
<template>
<button @click="emitValue">Emit Value</button>
</template>
<script>
export default {
methods: {
emitValue() {
this.$emit('custom-event', 'Value from child component');
}
}
};
</script>
父组件:
<template>
<child-component @custom-event="handleEvent"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
handleEvent(value) {
console.log(value); // Output: Value from child component
}
}
};
</script>
三.Provide/Inject
祖先组件:
<template>
<child-component></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
provide: {
providedValue: 'Value from ancestor component'
}
};
</script>
后代组件:
<template>
<div>{{ injectedValue }}</div>
</template>
<script>
export default {
inject: ['providedValue'],
computed: {
injectedValue() {
return this.providedValue;
}
}
};
</script>
四.Vuex
创建store.js文件:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
globalValue: 'Global value'
},
mutations: {
updateGlobalValue(state, payload) {
state.globalValue = payload;
}
},
actions: {
updateGlobalValue({ commit }, payload) {
commit('updateGlobalValue', payload);
}
},
getters: {
getGlobalValue(state) {
return state.globalValue;
}
}
});
在main.js中引入store.js:
import Vue from 'vue';
import store from './store';
new Vue({
store,
render: h => h(App)
}).$mount('#app');
组件中使用Vuex:
<template>
<div>
<div>{{ globalValue }}</div>
<button @click="updateValue">Update Value</button>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
computed: {
...mapState(['globalValue'])
},
methods: {
...mapActions(['updateGlobalValue']),
updateValue() {
this.updateGlobalValue('New global value');
}
}
};
</script>
五.$attrs/listeners:
高层组件:
<template>
<child-component v-bind="$attrs" v-on="$listeners"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
};
</script>
低层组件:
<template>
<input v-bind="$attrs" v-on="$listeners">
</template>
六.$parent 和 $children
父组件:
<template>
<child-component></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
mounted() {
console.log(this.$children); // Output: [ChildComponent instance]
}
};
</script>
子组件:
<template>
<div>{{ $parent.propValue }}</div>
</template>
<script>
export default {
mounted() {
console.log(this.$parent.propValue); // Output: Value from parent component
}
};
</script>
七.$refs
父组件:
<template>
<child-component ref="childComponent"></child-component>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
mounted() {
console.log(this.$refs.childComponent);
this.$refs.childComponent.someMethod(); // Call a method in child component
}
};
</script>
子组件:
<template>
<div>Child Component</div>
</template>
<script>
export default {
methods: {
someMethod() {
console.log('Method called in child component');
}
}
};
</script>
八.EventBus
事件总线:
// eventBus.js
import Vue from 'vue';
export const eventBus = new Vue();
// main.js
import { eventBus } from './eventBus';
new Vue({
created() {
eventBus.$on('custom-event', this.handleEvent);
},
methods: {
handleEvent(value) {
console.log(value); // Output: Value from child component
}
},
render: h => h(App)
}).$mount('#app');
子组件:
<template>
<button @click="emitValue">Emit Value</button>
</template>
<script>
import { eventBus } from './eventBus';
export default {
methods: {
emitValue() {
eventBus.$emit('custom-event', 'Value from child component');
}
}
};
</script>
九.状态提升
父组件:
<template>
<div>
<child-component v-bind:propValue="sharedValue" v-on:updateValue="updateSharedValue"></child-component>
<another-child-component v-bind:propValue="sharedValue"></another-child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
import AnotherChildComponent from './AnotherChildComponent.vue';
export default {
components: {
ChildComponent,
AnotherChildComponent
},
data() {
return {
sharedValue: ''
};
},
methods: {
updateSharedValue(value) {
this.sharedValue = value;
}
}
};
</script>
子组件1:
<template>
<div>
<input v-model="propValue" @input="updateValue">
</div>
</template>
<script>
export default {
props: ['propValue'],
methods: {
updateValue() {
this.$emit('updateValue', this.propValue);
}
}
};
</script>
子组件2:
<template>
<div>
<div>{{ propValue }}</div>
</div>
</template>
<script>
export default {
props: ['propValue']
};
</script>
十.URL参数
路由配置:
import VueRouter from 'vue-router';
const router = new VueRouter({
routes: [
{
path: '/component/:id',
component: MyComponent
}
]
});
组件中获取参数:
<template>
<div>{{ $route.params.id }}</div>
</template>
<script>
export default {
created() {
console.log(this.$route.params.id);
}
};
</script>
在上面的代码中,我们使用不同的方式展示了传值的示例:
- Props:使用props属性将数据传递给子组件。
- Emit:子组件通过触发自定义事件,父组件通过@custom-event监听事件并处理传递的数据。
- Provide/Inject:在祖先组件中提供数据,后代组件使用inject接收数据。
- Vuex:使用Vuex库来管理全局状态,组件之间通过store进行状态共享。
- $attrs/$listeners:透传属性和事件给子组件。
- $parent/$children:通过parent和children访问父子组件的实例。
- refs:使用ref属性给组件添加引用,通过refs访问组件实例。
- EventBus:通过事件总线发布和订阅事件进行组件间通信。
- 状态提升:将共享数据放到共同的父组件中,通过props和emit在父组件中传递数据给子组件。
- URL参数:使用路由的params、query、hash等方式传递数据。
请注意,以上代码仅用于演示不同的传值方式,具体实现可能需要在组件中添加逻辑和事件处理。