vue -- 组件间传值
内容提要
- 父组件 -> 子组件 (props)
- 子组件 -> 父组件 (emit)
- sync修饰符(在2.3.0重新被引入)
- 同级组件间(兄弟组件)(EventBus)及EventBus被多次触发
- vuex
正文
父组件 -> 子组件 (props)
//在子组件(Child1.vue)中:<template>
<div>
//需要从父组件中获取数据的部分
<div>{{childmsg1}}</div>
<div>{{childmsg2}}</div>
</div>
</template>
<script>
export default {
data() {
return {
...
}
},
props:['childmsg1','childmsg2'], //可声明多个值,若为驼峰命名如childMsg在父组件中childMsg/child-msg都能被解析
methods:{
...
}
}
</script>
//在父组件(Parent.vue)中:
<template>
<div>
<child1 :childmsg1='sendChild1' :childmsg2='sendChild2'></child1>
</div>
</template>
<script>
import child1 from './Child1.vue';
export default {
data() {
return {
sendChild1:'我是要传给子组件的数据1',
sendChild2:'我是要传给子组件的数据2',
}
},
components:{
child1,
}
}
</script>
子组件 -> 父组件 (emit)
//在子组件(Child1.vue)中:<template>
<div>
<div @click='sendMsg'>点击我向父组件发送数据</div>
</div>
</template>
<script>
export default {
methods:{
sendMsg(){
this.$emit('child','我是子组件传递过来的数据');
}
}
}
</script>
//在父组件(Parent.vue)中:
<template>
<div>
<!--<child1 @child='getChildMsg'></child1> -->
<component :is="'child1'" @child='getChildMsg'></component>
</div>
</template>
<script>
import child1 from './Child1.vue';
export default {
components:{
child1,
},
methods:{
getChildMsg(res){
console.log(res); //'我是子组件传递过来的数据'
}
}
}
</script>
sync修饰符(在2.3.0重新被引入)
一般情况下props是单向绑定的,即父组件更新了,子组件才更新,不应该在子组件中改变props。
但实际应用中我们有这个同步的需求,要解决这个问题,就用到了sync修饰符对props双向绑定。
//在子组件(Child1.vue)中:<template>
<div>
<p>父组件传过来的数据为{{s1}}</p>
<div @click="changeParent">点击</div>
</div>
</template>
<script>
export default {
props:['s1'],
methods:{
changeParent(){
console.log(`父组件穿过来的数据为`+this.s1);
this.$emit('update:s1','改变了') //此时s1跟s1Val的值都发生了改变
},
}
}
</script>
//在父组件(Parent.vue)中:
<template>
<div>
<child1 :s1.sync="s1Val"></child1>
</div>
</template>
<script>
import child1 from './Child1.vue';
export default {
data() {
return {
s1Val:'syncmsg'
}
},
components:{
child1,
},
}
</script>
同级组件间(兄弟组件)(EventBus)
1、创建文件bus.js,内容如下:
import Vue from 'vue';export default new Vue();
2、在需要传输与接收的组件中引入:
import Bus from '../bus.js';
也可将1、2步合并在main.js中设置全局的变量,则不用在每个文件中引用,3、4照常。
window.eventbus=new Vue();//组件中可以直接使用,如下:
created(){
eventbus.$on('sen',this.fun)
},
3、发送数据
sendMsg(){ Bus.$emit('msg','我是发出的信息!');
}
4、接收数据
created(){ Bus.$on('msg',function(res){
console.log(res); //我是发出的信息!
//若要在此处改变页面的数据,注意this的指向
})
}
EventBus被多次触发
问题表现:就是我第一次跳转页面并触发事件的时候,控制台并没有输出。但是当我第二次再点击触发事件的时候,就会输出一个测试数据。再一次进去点击,就输出两次……依次增加了。
问题分析:当我们还在页面A的时候,页面B还没生成,也就是页面B中的created中所监听的来自于A中的事件还没有被触发。这个时候当你A中emit事件的时候,B其实是没有监听到的。
当你从页面A到页面B跳转的时候,发生了什么?首先是先B组件先created然后beforeMount接着A组件才被销毁,A组件才执行beforeDestory,以及destoryed.
解决方案:我们可以把A页面组件中的emit事件写在beforeDestory中去。因为这个时候,B页面组件已经被created了,也就是我们写的$on事件已经触发了。
//A组件中:beforeDestroy () {
Bus.$emit('sen','hello!');
}
//B组件中:
methods:{
fun(res){
console.log(res);
}
},
created(){
Bus.$on('sen',this.fun);
},
//这段代码恢复紧接着下一条问题
beforeDestroy () {
Bus.$off('sen', this.fun);
},
此时我们又发现了新的问题:虽然第一次有了数据,但是之后还是有依次增加的问题。
原因:$on事件是不会自动清楚销毁的,需要我们手动来销毁。
解决方案:在B组件页面中添加Bus.$off来关闭。
小结:如果想要用EventBus来进行页面组件之间的数据传递,需要注意两点:1、组件A中$emit事件应在beforeDestory生命周期内。
2、组件B内的$on记得要销毁。
Vuex
Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
如果不打算开发大型单页应用,使用Vuex可能是繁琐冗余的。使用上面的方法可以满足大多需求,所以这篇先不讲了,下篇见~
以上是 vue -- 组件间传值 的全部内容, 来源链接: utcz.com/z/379493.html