一、Vue组件:父传子
1.子组件获取父组件的数据
子组件通过prop获取父组件的数据。注:input 中的v-model自动监听数据的变化
<body>
<div id="app">
<father></father>
</div>
</body>
<!-- 父组件 -->
<template id="father">
<div>
<h1>父组件</h1>
<input type="text" v-model="message">
<hr>
<son :getmoney='money' :flow='num' :msg='message'></son>
</div>
</template>
<!-- 子组件 -->
<template id="son">
<div>
<h1>子组件</h1>
<h3> {{getmoney}}</h3>
<h3> {{msg}}</h3>
<button @click='func(msg)'>点击</button>
</div>
</template>
<script>
// 父组件用prop传值
var son = {
template: '#son',
props: ['getmoney', 'flow', 'msg'],
methods: {
func(val) {
console.log(val)
}
}
}
Vue.component('father', {
template: '#father',
data() {
return {
money: '爸爸给你10万块',
num: 10,
message: '',
}
},
components: {
son
}
})
var vue = new Vue({
el: '#app',
data: {},
methods: {}
})
</script>
分页面展示
<template>
<div id="app">
<h1>父组件</h1>
<input type="text" v-model="message">
<hr>
<child :getmoney='money' :flow='num' :msg='message'/>
</div>
</template>
<script>
import child from './components/child.vue'
export default {
name: 'App',
components: {
child
},
data() {
return {
money: '爸爸给你10万块',
num: 10,
message: '',
}
},
}
</script>
<template>
<div class="child">
<h1>子组件</h1>
<h3> {{getmoney}}</h3>
<h3> {{msg}}</h3>
<button @click='func(msg)'>点击</button>
</div>
</template>
<script>
export default {
name: 'child',
props: ['getmoney', 'flow', 'msg'],
methods: {
func(val) {
console.log(val)
}
}
}
</script>
2.子组件调用父组件的方法
Vue中子组件调用父组件的方法,这里有三种方法提供参考
第一种方法是直接在子组件中通过this.$parent.event
来调用父组件的方法
父组件
<template>
<div>
<child></child>
</div>
</template>
<script>
import child from '~/components/child';
export default {
components: {
child
},
methods: {
fatherMethod() {
console.log('测试');
}
}
};
</script>
子组件
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
methods: {
childMethod() {
this.$parent.fatherMethod();
}
}
};
</script>
第二种方法是在子组件里用$emit
向父组件触发一个事件
父组件监听这个事件就行了,相当于子组件给父组件传值。如tree中暴露出接口,父组件直接使用。
父组件
<template>
<div>
<child @fatherMethod="fatherMethod"></child>
</div>
</template>
<script>
import child from '~/components/dam/child';
export default {
components: {
child
},
methods: {
fatherMethod() {
console.log('测试');
}
}
};
</script>
子组件
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
methods: {
childMethod() {
this.$emit('fatherMethod');
}
}
};
</script>
第三种是父组件把方法传入子组件中,在子组件里直接调用这个方法
父组件
<template>
<div>
<child :fatherMethod="fatherMethod"></child>
</div>
</template>
<script>
import child from '~/components/dam/child';
export default {
components: {
child
},
methods: {
fatherMethod() {
console.log('测试');
}
}
};
</script>
子组件
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
props: {
fatherMethod: {
type: Function,
default: null
}
},
methods: {
childMethod() {
if (this.fatherMethod) {
this.fatherMethod();
}
}
}
};
</script>
三种都可以实现子组件调用父组件的方法,但是效率有所不同,根据实际需求选择合适的方法。
二、Vue组件:子传父
1.父组件获取子组件的数据
方法1:给相应的子组件标签上加 ref ="child"
,使用this.$refs.child.msg
获取msg的内容
<template>
<div id="app">
<h1>父组件</h1>
<button @click='getmsg'>点击</button>
<div>{{msg}}</div>
<hr>
<child ref="child"/>
</div>
</template>
<script>
import child from './components/child.vue'
export default {
name: 'App',
components: {
child
},
data() {
return {
msg:''
}
},
methods: {
getmsg() {
this.msg=this.$refs.child.msg;
}
}
}
</script>
<template>
<div class="child">
<h1>子组件</h1>
</div>
</template>
<script>
export default {
name: 'child',
data() {
return {
msg: '这是子组件传给父组件的数据'
}
},
}
</script>
通过ref绑定,使用
this.$refs.child.msg
获取msg的内容。该方法父组件可以获取到子组件的方法,并调用。
方法2:通过$emit()
<body>
<div id="app">
<father></father>
</div>
</body>
<!-- 父组件 -->
<template id="father">
<div>
<h1>父组件</h1>
{{message}}
<hr>
<son @sendmsg="getmsg"></son>
</div>
</template>
<!-- 子组件 -->
<template id="son">
<div>
<h2>子组件</h2>
<button @click="click">点击</button>
</div>
</template>
<script>
// 子组件
var son = {
template: '#son',
data() {
return {
msg: '这是子组件传给父组件的数据'
}
},
methods: {
click() {
this.$emit('sendmsg', this.msg)//触发事件,用方法接收
}
}
}
// 父组件
Vue.component('father', {
template: '#father',
components: {
son
},
data() {
return {
message: '',
}
},
methods: {
getmsg(val) {
console.log(val);
this.message = val
}
}
})
var vue = new Vue({
el: '#app',
data: {},
methods: {}
})
</script>
分页面展示
<!-- 父组件 -->
<template>
<div id="app">
<h1>父组件</h1>
{{msg}}
<hr>
<child @sendmsg="getmsg"/>
</div>
</template>
<script>
import child from './components/child.vue'
export default {
name: 'App',
components: {
child
},
data() {
return {
msg:''
}
},
methods: {
getmsg(val) {
console.log(val);
this.msg=val;
}
}
}
</script>
<!-- 子组件 -->
<template>
<div class="child">
<h1>子组件</h1>
<button @click='func'>点击</button>
</div>
</template>
<script>
export default {
name: 'child',
data() {
return {
msg: '这是子组件传给父组件的数据'
}
},
methods: {
func(){
this.$emit("sendmsg",this.msg)//触发事件,用方法接收
}
}
}
</script>
从上面可以看出,当
this.$emit()
携带参数时,可以传参到父组件,同时可以调用父组件的方法;
2.父组件调用子组件的方法
给相应的子组件标签上加 ref ="child"
,然后通过this.$refs.child.func()
获取func()的方法。
三、Vue的$on,$emit的使用
vue中使用 $emit(eventName)
触发事件,使用 $on(eventName)
监听事件,为同级事件。
$emit(eventName)
触发当前实例上的事件,附加参数都会传给监听器回调。
$on(eventName)
监听当前实例上的自定义事件。事件可以由 vm.$emit
触发。回调函数会接收所有传入事件触发函数的额外参数。
下面通过几个实例来演示一下怎么使用
实例1 本页面单个事件
<template>
<div>
<el-button type="primary" @click="isClick">点击</el-button>
</div>
</template>
<script>
export default {
methods: {
isClick() {
this.$emit('isLeft', '点击事件!');//与this.$on 同级使用
}
},
mounted() {
this.$on('isLeft', (val) => {
console.log(val);
});
}
}
</script>
以上代码,是通过按钮的点击事件,然后this.$emit
传递事件,然后this.$on
捕获本页面的事件
实例2 本页面多个事件
<template>
<div>
<el-button type="primary" @click="isClick">点击</el-button>
<el-button type="primary" @click="isClickOther">点击</el-button>
</div>
</template>
<script>
export default {
methods: {
isClick() {
this.$emit('isLeft', '点击事件!');
},
isClickOther() {
this.$emit('isRight', ['点击1', '点击2']);
}
},
mounted() {
this.$on('isLeft', (val) => {
console.log(val);
});
this.$on('isRight', (...val) => {
console.log(val);
});
this.$on(['isLeft', 'isRight'], () => {
console.log(666);
});
}
}
</script>
以上例子,是本页面的两个点击事件,可以同时监听两个事件,也可以同时传多个参数
实例3 非父子组件传值(通过bus
传值)
子组件1
<template>
<div>
<div>left</div>
<el-button type="primary" @click="isClick">点击</el-button>
</div>
</template>
<script>
import eventBus from './js/eventBus';
export default {
methods: {
isClick() {
eventBus.$emit('isLeft', '点击事件!');
}
}
}
</script>
子组件2
<template>
<div>
<div>right</div>
{{ name }}
</div>
</template>
<script>
import eventBus from './js/eventBus';
export default {
data() {
return {
name: 'right默认值'
};
},
mounted() {
eventBus.$on('isLeft', (info) => {
this.name = info ;
});
}
}
</script>
父组件
<template>
<div>
<el-row>
<el-col :span="12">
<leftChlid></leftChlid>
</el-col>
<el-col :span="12">
<rightChild ></rightChild>
</el-col>
</el-row>
</div>
</template>
<script>
import leftChlid from './components/leftChlid'
import rightChild from './components/rightChild'
export default {
components: {
leftChlid,
rightChild
}
}
</script>
以上例子就是 left组件传值给bus
,然后right组件监听 bus
的isLest事件
,当left组件触发事件的时候,right组件就会触发方法,替换页面的值
小结
1.使用 $emit
传递事件
2.使用 $on
监听事件
3.可以本页面使用,也可以父子组件使用,也可以非关联组件使用
四、总结
1:父组件向子组件传值:使用 prop
向子组件传值;
2:子组件实时监听父组件传来的值的变化:使用 watch
去监听父组件传来的值;
3:父组件可以通过 this.$refs.name.
去访问子组件的值或方法;
4:子组件可以通过 this.$parent.
去访问父组件的值或方法;
5:父组件可以通过 this.$store.dispatch
去监听子组件的值;
下次我们说说$attrs和$listeners
。