1.父组件向子组件传值(只能父向子传值,子组件不能更新父组件内的data)
//父组件
<template>
<div>
<div>父组件</div>
<child :message="parentMsg"></child>
</div>
</template>
<script>
import child from './child' //引入child组件
export default {
data() {
return {
parentMsg: '来自父组件' //在data中定义需要传入的值
}
},
components: {
child
}
}
</script>
//子组件使用props属性接收来自父组件的值
<template>
<div>
<div>{{message}}</div>
</div>
</template>
<script>
export default {
props: {
message: String //定义传值的类型<br>
},
//或者props:["message"]
data: {},
watch:{
message(val,oldVal){
//……
}
},
}
</script>
<style>
</style>
2.父组件调用子组件的方法(用$ref调用)
ref 被用来给DOM元素或子组件注册引用信息。引用信息会根据父组件的 $refs 对象进行注册。如果在普通的DOM元素上使用,引用信息就是元素; 如果用在子组件上,引用信息就是组件实例
注意:只要想要在Vue中直接操作DOM元素,就必须用ref属性进行注册
//父组件
<template>
<div @click="parentMethod">
<children ref="child"></children>
</div>
</template>
<script>
import children from 'children.vue'
export default {
data(){
return {
}
},
components: {
children
},
methods:{
parentMethod() {
this.$refs.child.childMethod();
}
}
}
</script>
<template>
<div>
</div>
</template>
<script>
export default {
data(){
return {
}
},
methods:{
childMethod() {
alert('我来自子组件')
}
}
}
</script>
3.子组件传值给父组件(子组件使用this.$emit()向父组件传值)
//父组件
<template>
<div>
<asd @listenToChildEvent1="showMsgFromChild"></asd>
<asd @listenToChildEvent="showMsgFromChild"></asd>
<div>{{ sss }}</div>
</div>
</template>
<script>
import asd from './compontents/asd.vue'
export default {
components:{asd},
data () {
return {
sss:''
}
},
methods: {
showMsgFromChild(data){
this.sss = data
},
}
}
</script>
//子组件
<template>
<button @click="sendMsgToParent()">
我是子组件,点击我向父组件传值
</button>
</template>
<script>
export default {
data(){
return {
message:'我是子组件的数据'
}
},
methods:{
sendMsgToParent() {
this.$emit("listenToChildEvent1",this.message)
this.$emit('listenToChildEvent',"123")
}
}
}
</script>
4.子组件调用父组件的方法(传值就是利用方法调用实现的,使用方法同上。)
5.子组件同步修改父组件值,实现“双向绑定”
上面提到子组件使用props方法去接收父组件传递的值时不能修改父组件data中的值。
vue的prop是单向下行绑定:父级的prop的更新会流到子组件中,但是反过来不行,可有时我们需要同步修改父组件中的data值。
sync是vue中用于“双向绑定”的语法糖。
<text-document :title.sync="doc.title"></text-document>
当子组件需要更新 title 的值时,它需要显式地触发一个更新事件:
this.$emit('update:title', newValue)
实例演示:
<template>
<div class="details">
<myComponent :show.sync='valueChild' style="padding: 30px 20px 30px 5px;border:1px solid #ddd;margin-bottom: 10px;"></myComponent>
<button @click="changeValue">toggle</button>
</div>
</template>
<script>
import Vue from 'vue'
Vue.component('myComponent', {
template: `<div v-if="show">
<p>默认初始值是{{show}},所以是显示的</p>
<button @click.stop="closeDiv">关闭</button>
</div>`,
props:['show'],
methods: {
closeDiv() {
this.$emit('update:show', false); //触发 input 事件,并传入新值
}
}
})
export default{
data(){
return{
valueChild:true,
}
},
methods:{
changeValue(){
this.valueChild = !this.valueChild
}
}
}
</script>
如果未触发事件 this.$emit(‘update:show’, false); 则外部感知不到子组件内部对show的改变,依然认为此事的值是true,导致弹框点击打开一次之后,后面再不会打开。
6.this.
e
m
i
t
和
t
h
i
s
.
emit和this.
emit和this.on的理解
$emit
- this $emit(‘自定义事件名’,要传送的数据);
- 触发当前实例上的事件,要传递的数据会传给监听器
$on
- VM. o n ( ′ 事 件 名 ′ , c a l l b a c k ) − − − − − − − − − − − − − − − − − − − − c a l l b a c k 回 调 on('事件名',callback) --------------------callback回调 on(′事件名′,callback)−−−−−−−−−−−−−−−−−−−−callback回调emit要传送的数据;
- 监听当前实例上自定义时间;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>孙三峰--博客园</title>
<script type="text/javascript" src="js/vue2.0.3.js" ></script>
<script type="text/javascript">
//准备一个空的实例对象
var Event = new Vue();
var A={
template:`
<div style="border: 1px solid red; margin-bottom: 10px; width: 300px;">
<h4>A组件</h4>
<p>{{a}}</p>
<input type="button" value="把A数据给C" @click="send" />
</div>
`,
data(){
return {
a:'我是A里面的数据'
}
},
methods:{
send(){ //A发送数据
Event.$emit('a-msg',this.a);
}
}
};
var B={
template:`
<div style="border: 1px solid green; margin-bottom: 10px; width: 300px;">
<h4>B组件</h4>
<p>{{b}}</p>
<input type="button" value="把B数据给C" @click="send" />
</div>
`,
data(){
return {
b:'我是B里面的数据'
}
},
methods:{
send(){
Event.$emit('b-msg',this.b);
}
}
};
var C={
template:`
<div style="border: 1px dotted green; margin-bottom: 10px;width: 300px;">
<h4>我是C组件,我在坐等接收数据</h4>
<p>{{a}}</p>
<p>{{b}}</p>
</div>
`,
data(){
return{
a:'',
b:''
}
},
mounted(){ //两种接收的方式
var _this = this;
Event.$on('a-msg',function(a){
_this.a=a;
});
Event.$on('b-msg',function(b){
this.b = b;
}.bind(this))
}
};
window.onload=function(){
new Vue({
el:'#box',
data:{
},
components:{
'com-a':A,
'com-b':B,
'com-c':C
}
})
}
</script>
</head>
<body>
<div id="box">
<com-a></com-a>
<com-b></com-b>
<com-c></com-c>
</div>
</body>
</html>