1.兄弟组件传值
兄弟组件之间就需要一个中间值,我在这里称为bus。在vue文件main.js中,我们利用 Vue.prototype.bus=new Vue() 来定义,此时我们就有了一个中间量
这是第一个子组件 -- 从这里向另外一个子组件传值
<template>
<div>
<div id="title">我是第一个子组件</div>
我要给第二个兄弟发信息,内容是:
<input type="text" v-model="to" />
</div>
<button @click="toBrother">点我给兄弟传值</button>
</div>
</template>
<script>
export default {
data() {
return {
to: "哈喽老二"
};
},
methods: {
toBrother() {
this.bus.$emit("toBrother", this.to);
}
}
};
</script>
在这里我在button上绑定了一个方法,在方法内部使用中间变量bus中的$emit来传递值,参数同子传父的参数一致。
这是第二个子组件--用来做接收方
<template>
<div>
<div id="title">我是第二个子组件</div>
<div>我得到的兄弟组件信息是:{{get}}</div>
</div>
</template>
<script>
export default {
data() {
return {
get: ""
};
}
beforeCreate() {
this.bus.$on("toBrother", msg => {
this.get = msg;
});
}
};
</script>
在第二个子组件里面通过beforeCreate生命周期来获得传过来的值,这时候需要用this.bus.emit定义的第一个方法名,第二个参数是一个方法,此方法带一个返回参数。在这里我使用箭头函数。
2. attrs、listeners (属性,事件)
多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法 listeners。(解决跨级组件传值)
attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 inheritAttrs 选项一起使用
listeners" 传入内部组件 简单来说:listeners 是两个对象,listeners里存放的是父组件中绑定的非原生事件。
<template>
<div class="app">
App组件接收传过来的值:{{ myDate }}
<other :myDate="myDate" :foo="foo" title="标题"></other>
</div>
</template>
<script>
import other from "./components/test/other"
export default{
name:'app',
data(){
return{
myDate:'我是App默认数据',
foo:"foo"
}
},
components: {
"other": other
}
}
</script>
//other.vue
<template>
<div>
<p>通过props传值foo: {{ foo }}</p>
<p>展示$attrs: {{ $attrs }}</p> <!-- "myDate": "我是App默认数据", "title": "标题" -->
<!--<child-com2 v-bind="$attrs">还可以继续延伸</child-com2>-->
</div>
</template>
<script>
export default {
// 可以关闭自动挂载到组件根元素上的没有在props声明的属性,即组件不继承根元素特性
inheritAttrs: false,
props:{
foo:String // foo作为props属性绑定,不包含在$attrs中
}
}
</script>
3. provide、inject
两者一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。即:祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。
provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。为高阶插件/组件库提供用例。
<template>
<div class="app">
<son></son>
</div>
</template>
<script>
import son from "./components/test/son"
export default{
name:'app',
data(){
return{
myDate:'App默认数据'
}
},
provide(){
return{
AppDate : this.myDate
}
},
components: {
"son": son
}
}
</script>
// son.vue
<template>
<div>
<p>获取从App传过来的值 {{ AppDate }}</p>
</div>
</template>
<script>
export default {
inject:['AppDate']
}
</script>
$attrs
<input :value="value" @input="oninput" v-bin="$attrs"/>
// 这个就是把除了props里的属性,都加到当前元素上
// 父组件
<kvue name="123" abc="456"></kvue >
// kvue 组件
<div>
<input :value="value" @input="oninput" v-bind="$attrs"/>
</div>
<script>
export default {
i nheritAttrs:false, //避免kvue 组件里div继承abc,name之类的属性
};
</script>