要点
一、父组件给子组件传值–数据
- 父组件调用子组件的时候,给子组件绑定一个动态属性(:xx=yy),属性值yy来自父组件
- 在子组件内, 用props对象(与data,methods同级),接收父组件传来的属性 [“xx”]
二、父组件主动获取子组件的数据和方法
- 父组件调用子组件的时候,给子组件一个属性,ref=“xxx”
- 在父组件里通过:
this.$refs.xxx
.数据–获取数据,this.$refs.xxx.
方法–调用方法
三、子组件主动获取父组件的数据和方法
在子组件里通过:this.$parent.数据
–获取数据,this.$parent.方法
--调用方法
四、非父子组件(兄弟组件)传值
- 新建一个js文件,引入Vue,实例化Vue,暴露这个实例
- 在要广播的地方引入刚才的定义的实例
- 通过–
实例名.$emit('广播名称',数据)
—进行广播 - 在要接收数据的地方监听广播----通过–
实例名.$on('广播名称',function(){})
五、爷组件给孙组件传值
$attrs:包含了所以父组件在孙组件上设置的属性
$listeners:包含了作用在这个组件上所有的监听器(监听事件),可以通过 v-on=" $listeners"
将事件监听指向这个组件内的子元素(包括内部的子组件)。
(1).通过属性传递(爷->孙)
1.在爷爷组件中,给父组件绑定一个属性:xx=“1”,
2.给父组件用 子组件用v-bind="$attrs"
获取爷爷组件的传给父组件的属性
3.在子组件中,通过this.$attrs.xx
获取爷爷组件传给父组件的值
(2).通过事件传递(孙->爷)
- 在子组件中,自定义事件 并传值
this.$emit("自定义事件名",20)
- 给父组件,给子组件设置
v-on="$listeners"
- 在爷爷组件中,通过@自定义事件名的方式触发爷爷组件自己的方法,监听算组件传来的数据
父组件组件在其中传递props以及事件的过程中,不必在写多余的代码,仅仅是将$attrs
以及$listeners
向上或者向下传递即可。
父组件向子组件传值
- 父组件发送的形式是以属性的形式绑定值到子组件身上。
- 然后子组件用属性props接收
- 子组件的mounted函数先于父组件的mounted函数调用
若:
1.父组件在mounted函数中将原data定义的arr:[ ],新赋值为arr:[1,2,3],
2.父组件给子组件传值,子组件获得arr
3.子组件在mounted函数中打印arr,打印的结果为[ ]空
原因:子组件的mounted函数先于父组件的mounted函数调用,因为子组件调用mounted时,父组件还没有调用mounted,此时arr:[ ]。
等到父组件调用mounted后,才会有arr:[1,2,3]
父组件:
<template>
<div id="app">
<div>{{pmsg}}</div>
<menuitem title='来自父组件的值'></menuitem>
<menuitemq :title='ptitle' content='hello'></menuitemq>
</div>
</template>
<script>
import menuitemq from '@/components/menuitemq'
export default {
// name: '',
data () {
return {
pmsg: '父组件中内容',
ptitle: '动态绑定属性'
};
},
components: {
menuitemq
},
mounted () {},
methods: {}
}
</script>
<style lang='stylus' scoped>
</style>
子组件:
<template>
<div>{{msg + "----" + title + "-----" + content}}</div>
</template>
<script>
export default {
// 3、 子组件用属性props接收父组件传递过来的数据,注册属性
props: ['title', 'content'],
data() {
return {
msg: '子组件本身的数据'
}
},
components: {},
mounted () {},
methods: {}
}
</script>
<style lang='stylus' scoped>
</style>
子组件向父组件传值
- 子组件用$emit()触发事件
- $emit() 第一个参数为 自定义的事件名称 第二个参数为需要传递的数据
- 父组件用v-on 监听子组件的事件
父组件:
<template>
<div id="app">
<div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div>
<!-- 2 父组件用v-on 监听子组件的事件
这里 enlarge-text 是从 $emit 中的第一个参数对应 handle 为对应的事件处理函数
-->
<menuitemq :parr='parr' @enlargetext='handle'></menuitemq>
</div>
</template>
<script>
import menuitemq from '@/components/menuitemq'
export default {
// name: '',
data () {
return {
pmsg: '父组件中内容',
parr: ['apple','orange','banana'],
fontSize: 10
};
},
components: {
menuitemq
},
mounted () {},
methods: {
handle: function(val){
// 扩大字体大小
this.fontSize += val;
}
}
}
</script>
<style lang='stylus' scoped>
</style>
子组件:
<template>
<div>
<ul>
<li :key="index" v-for="(item,index) in parr" >{{item}}</li>
</ul>
<button @click="fn">扩大父组件中字体大小</button>
<button @click="fm">扩大父组件中字体大小</button>
</div>
</template>
<script>
export default {
name: "",
data() {
return {};
},
props: ["parr"],
components: {},
mounted() {},
methods: {
fn(){
this.$emit("enlargetext",5)
},
fm(){
this.$emit("enlargetext",10)
}
}
};
</script>
<style lang='stylus' scoped></style>
兄弟之间的传递
- 兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据
- 提供事件中心 var hub = new Vue()
- 传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)
- 接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名
- 销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据
兄弟a----testa.vue
<template>
<div>
<div>a:{{num}}</div>
<div>
<button @click='handle'>点击</button>
</div>
</div>
</template>
<script>
import Bus from '@/bus.js'
export default {
name: "",
data() {
return {
num: 0
};
},
props: [],
components: {},
mounted() {
// 3、接收数据方,通过mounted(){} 钩子中 触发hub.$on(方法名
Bus.$on('a-event', (val) => {
this.num += val;
});
},
methods: {
handle(){
//2、传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据) 触发兄弟组件的事件
Bus.$emit('b-event', 2);
// console.log("to")
console.log(this)
}
}
};
</script>
<style lang='stylus' scoped></style>
兄弟b----testb.vue
<template>
<div>
<div>b:{{num}}</div>
<div>
<button @click='handle'>点击</button>
</div>
</div>
</template>
<script>
import Bus from '@/bus.js'
export default {
name: '',
data () {
return {
num: 0
};
},
props:[],
components: {},
mounted () {
// console.log(this)
// 3、接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名
Bus.$on('b-event', (val) => {
console.log(val)
this.num += val;
console.log(this.num)
});
},
methods: {
handle(){
//2、传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据) 触发兄弟组件的事件
Bus.$emit('a-event', 1);
}
}
}
</script>
<style lang='stylus' scoped>
</style>
父组件–father.vue
<template>
<div id="app">
<div>父组件</div>
<div>
<button @click='handle'>销毁事件</button>
</div>
<testa></testa>
<testb></testb>
</div>
</template>
<script>
import testa from '@/components/testa'
import testb from '@/components/testb'
import Bus from '@/bus.js'
export default {
// name: '',
data () {
return {
};
},
components: {
testa,
testb
},
mounted () {},
methods: {
handle:()=>{
//4、销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据
Bus.$off('a-event');
Bus.$off('b-event');
}
}
}
</script>
<style lang='stylus' scoped>
</style>
总线—Bus.js
import Vue from 'vue'
var Bus = new Vue();
export default Bus;