vue -- 组件间传值

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

回到顶部