一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情
在项目开发过程中,最常用到的便是:vue组件间的传值。以下是本人总结的vue组件间传值的几种传值方式。首先可以大致区分为父子组件之间的传值,跨组件之间的传值和兄弟组件之间的传值。该文章讲解第二部分:跨组件之间的传值。
1. Provide / Inject
对于深层子组件需要父组件的内容时,也可以使用prop沿着组件链逐级传递,但会比较麻烦。实际上,我们可以使用provide/inject。无论组件层级结构多深,父组件都可以通过poject来提供数据,而子组件可以通过inject来接受使用这些数据。
父组件:
<script>
export default {
data(){
return{
myName:'vivi'
}
}
provide(){
return{
name: myName
}
}
}
</script>
需要接受信息的子组件
<script>
export default {
inject: ['name'],
created() {
console.log(this.name) // 父组件注入的信息: vivi
}
</script>
通常,我们会使用provide/inject来实现无感应式刷新页面,即刷新页面时不会出现空白页。具体demo如下:
首先在app.vue中注入reload更新方法。
<template>
<div id="app">
<router-view v-if="isRouterAlive"></router-view>
</div>
</template>
<script>
export default {
name:'app',
provide(){
return {
reload:this.reload
}
},
data(){
return {
isRouterAlive:true
}
},
methods:{
reload(){
this.isRouterAlive = false;
this.$nextTick(()=>{
this.isRouterAlive = true;
})
}
}
}
</script>
接着,在子组件中使用inject响应该方法。当需要触发刷新时,即可调用到父组件的reload方法。
<template>
<div>
<button @click="needReload">触发刷新页面</button>
</div>
</template>
<script>
export default {
inject:['reload'],
methods:{
needReload(){
this.reload();
}
}
}
</script>
2.$attrs和$listeners
-
$attrs包含了父作用域不被props接收到的数据(除class和style),这部分数据可以通过v-bind="$attrs "传入内部组件。可以理解为:$attrs就是一个容器对象,这个容器对象会存放:父组件传过来的且子组件未使用props声明接收的数据 -
$listeners包含了父作用域中的 (不含 .native 修饰器的) 所有v-on 事件,可以通过v-on="$listeners"传入内部组件接下来的实例则演示使用props逐级传递至嵌套的子组件和使用
$attrs和$listeners传递数据和方法的对比。父组件
<template> <div> <child :name1="'vivi'" :name2="'xiao xiao'" @toSon="mydata"></child> </div> </template> <script> export default { methods:{ components: { child }, mydata(){ console.log("我被孙子组件触发了"); } } } </script>子组件
<template> <div> <p>name1:{{name1}}</p> <p>name2:{{$attrs.name2}}</p> <childSon :name1="name1" v-bind="$attrs" v-on="$listeners"></childSon> </div> </template> <script> export default { props:['name1'], inheritAttrs:false, components: { childSon } } </script>孙子组件
<template> <div> <p>name1:{{name1}}</p> <p>name2:{{name2}}</p> <button @click="changeParents">点击触发父组件的mydata事件</button> </div> </template> <script> export default { props:['name1','name2'], methods:{ changeParents(){ this.$emit("toSon"); } } } </script>