首先我们把父传子,子传父结合在一起讲
-
父传子---------------props和$attrs:
父传子内嵌传值,子用props接收 -
子传父--------------$emit
子组件用 $emit向父组件传值
话不多说直接上例子,简单易懂
浏览器界面:
Father.vue
<template>
<div>
<div class='father'>
<input type="text" v-model='message'><br>
{{ cMessage }}
<div>
其他传值:data : {{ data }}
</div>
</div>
<Children :pre='message' :data='data' @del='deleteOne'></Children>
</div>
</template>
以上代码,father用pre和data向子组件传值,用@del接收子组件发送的请求
<script>
import Children from '@/components/Children.vue'
export default {
name: 'Father',
data: function (){
return {
message: '我是谁呀',
data:{
'name': 'Ace',
'age': 18
}
}
},
components:{
Children,
},
computed: {
cMessage(){
return 'Father Message: '+ this.message
}
},
methods: {
deleteOne () {
this.message = this.message.slice(0,this.message.length-1)
},
}
}
</script>
以上代码,把message和data通过pre和data传出去,如果接受到子组件的del请求,删除message最后一个字
Children.vue
<template>
<div class="children">
{{ childrenMessage }} <button @click='deleteOne'>del</button>
<br>
The leftover props: {{ messageLeft }}
</div>
</template>
以上代码,展示子组件接受的数据,通过计算属性输出,在用户点击删除按钮后出发click时间调用deleteOne方法
export default {
name: 'Children',
props:['pre'],
data: function (){
return {
left: ''
}
},
methods:{
deleteOne(){
this.$emit('del')
}
},
computed:{
childrenMessage(){
return 'Children Message Received: ' + this.pre
},
messageLeft(){
return this.$attrs
}
}
}
以上代码,用props[‘pre’]接收了父组件传来的pre(此处名字要相同),但是父组件传来的不止pre还有data,这时候没有用的data就会存在$attrs里面,以上代码同样把$attrs放在了页面。deleteOne方法会向父组件emit一个del,达到子组件向父组件传值的效果,注意此处子组件的del名字一定要与父组件接收的名字一样,如果子组件是:
this.$emit('delOne')
那么父组件就要用:
<children @delOne='anyOtherFuncName'> </children>
3. 非父子组件
页面展示:
输入down向下移,top向上移,left,right向左右移动,reset回归原点
main.js
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
data: {
bus: new Vue()
}
})
首先我们要在main.js里面加上一个Vue实例bus来达到传值目的
emit_test.vue
<template>
<div>
<input type="text" v-model="message">
<button @click="send">change</button><br>
</div>
</template>
input输入双向绑定message,点击change按钮执行send方法
export default {
name: 'Emit',
data: function (){
return {
message: ''
}
},
methods: {
send () {
this.$root.bus.$emit('change',this.message)
},
}
}
this.$root找到根实例然后用bus.$emit向另一个组件发送数据
(‘change’, this.message)
this.message是要发送出去的数据
receive_test.vue
<template>
<div class="bigBox">
<button @click='reset'>reset</button>
<div ref='toMove' class='block' :style="position"></div>
</div>
</template>
export default {
name: 'Rec',
data(){
return {
position:{
'top': '20px',
'left': '150px'}
}
},
/* 用$on接收 */
created(){
let that = this;
this.$root.bus.$on('change', t => {
switch (t){
case 'right':
that.moveRight();
break;
case 'left':
that.moveLeft();
break;
case 'down':
that.moveDown();
break;
case 'top':
that.moveTop();
break;
default:
break;
}
})
},
methods:{
moveRight(){
if (parseInt(this.position.left) >= 300) {
console.log('nonono');
return
}
let right = parseInt(this.position.left) + 5;
this.position.left = right + 'px';
},
moveLeft(){
if (parseInt(this.position.left) <= 0) {
console.log('nonono');
return
}
let left = parseInt(this.position.left) - 5;
this.position.left = left + 'px';
},
moveDown(){
if (parseInt(this.position.top) >= 580) {
console.log('nonono');
return
}
let top = parseInt(this.position.top) + 10;
this.position.top = top + 'px';
},
moveTop(){
if (parseInt(this.position.top) <= 20) {
console.log('nonono');
return
}
let top = parseInt(this.position.top) - 5;
this.position.top = top + 'px';
},
reset(){
this.$router.go('/');
}
}
}
以上用如下格式接收另一个组件发送的数据:
this.$root.bus.$on(‘change’, funcName(t){
…
})
首先,‘change’一定要和$emit的第一个参数相同
其次, funcName里面的t就是传过来的this.message
GOOD LUCK