1.父子组件通信:
1) 父向子传值:在父组件中,传递动态属性和静态属性,子组件通过props接收一个字符串数组或者对象( { }这种方式接受属性 可以对接受的值进行数据校验 );
2) 子向父传值:在父组件中,给子组件传递一个函数,子组件中,通过this.$emit('函数名',实参) 方法 调用函数同时传递参数;
<body>
<div id='app'>
<Father></Father>
</div>
<!-- 定义组件模板 -->
<template id="father">
<div>
<h1>我是父组件</h1>
<!-- 接收子组件传递过来的值 -->
<span>{{message}}</span>
<hr/>
<!-- 使用单项数据绑定的方式 -->
<!-- 属性名不能使用驼峰命名 -->
<!-- 通过 title和attr-a 给子组件传值-->
<Son title="son" :attr-a="msg" @deliver="deliverBySon"></Son>
</div>
</template>
<template id="son">
<div>
<h2>我是子组件</h2>
<h2>父组件传递过来数据:{{attrA}}</h2>
<button @click="$emit('deliver',sonMsg)">向父组件传值</button>
</div>
</template>
</body>
<script type='text/javascript'>
//父组件
Vue.component('Father', {
template: "#father",
data() {
return {
msg: "我是父亲",
message: ""
}
},
methods: {
deliverBySon(val) {
this.message = val
}
}
});
//子组件
Vue.component('Son', {
template: "#son",
//通过props接收
props: {
attrA: {
type: String,
default: "aaa"
},
title: String
},
data() {
return {
sonMsg: "我是儿子"
}
},
mounted() {
console.log(this.title) //返回"son"
},
});
//根组件
var vm = new Vue({
el: '#app',
data: {},
methods: {}
})
</script>
2.事件总线:兄弟组件传值: 通过中间Vue实例对象bus(快递员)进行数据传递,通过组件实例.$on('事件名称',事件方法(形参)) 声明事件, 通过 组件实例.$emit('事件名称',实参) 向外发送参数 触发事件.
<body>
<div id='app'>
<brother></brother>
<br/>
<sister></sister>
</div>
<!-- 兄弟组件 -->
<template id="brother">
<div>
<h1>我是哥哥</h1>
<button @click="handle">我要给姐姐传5</button>
<span>{{msg}}</span>
</div>
</template>
<!-- 姐妹组件 -->
<template id="sister">
<div>
<h1>我是姐姐</h1>
<button @click="handle">我要给哥哥传值6</button>
<span>{{msg}}</span>
</div>
</template>
<script type='text/javascript'>
//
let bus = new Vue();
//兄弟组件
Vue.component('brother', {
template: "#brother",
data() {
return {
broMsg: "我是哥哥",
msg: ''
}
},
methods: {
handle() {
bus.$emit('addFive', 5)
}
},
created() {
const that = this;
bus.$on('addSix', function(val) {
that.msg += val
})
},
});
//姐妹组件
Vue.component('sister', {
template: "#sister",
data() {
return {
sisMsg: "我是姐姐",
msg: ''
}
},
created() {
const that = this;
//通过组件实例.$on('事件名称',事件方法(形参)) 声明事件
bus.$on('addFive', function(val) {
console.log(this) //返回vue实例
console.log(that) //返回vue组件实例
that.msg += val
})
},
methods: {
//通过 组件实例.$emit('事件名称',实参) 向外发送参数 触发事件
handle() {
bus.$emit('addSix', 6)
}
}
})
var vm = new Vue({
el: '#app',
data: {},
methods: {}
});
</script>
</body>
3. 依赖注入:provide 和 inject 祖先组件给后代组件传值 :通过provide 注入原始家产 (用法基本和data是一直的) 是一个字符串数组或返回一个对象的函数, 通过inject接受 (和props用法基本上是一一致) 是一个字符串数组 或 一个对象. 不是响应式的.
<body>
<div id="app">
<!-- A嵌套B组件 B组件又嵌套C组件 -->
<a-component></a-component>
</div>
<script>
Vue.component('a-component', {
data() {
return {
jc1: 100
}
},
provide() {
return {
jc: this.jc1 // 通过获取自己data中数据然后将其注入给后代
}
},
template: `
<div>
我是A组件--{{jc1}}
<button @click='handleAdd'>点击A按钮</button>
<b-component></b-component>
</div>`,
methods: {
handleAdd() {
setTimeout(async() => {
const res = await Promise.resolve(5000)
this.jc1 = res
}, 2000)
}
},
})
//b组件
Vue.component('b-component', {
inject: ['jc'],
template: `
<div>
我是B组件--{{jc}}
<c-component></c-component>
</div>`
})
//c组件
Vue.component('c-component', {
inject: {
jcc: {
from: "jc", //用from表示需要注入的jc
default: () => {
return [1, 2, 3]
}
}
},
template: `<div>我是C组件--{{jcc}}</div>`
})
var vm = new Vue({
el: '#app'
})
</script>
</body>
4.v-model :子组件既要使用数据也要修改数据 .注意:一个组件上只能使用一次v-model ,默认传value和event 也可以通过model自定义属性名和事件名 实现父子组件通信
<body>
<div id='app'>
<father></father>
</div>
<!-- v-model的默认规则 -->
<!-- 传递:props
:followed="msg"
修改:自定义事件
@updateFollowed="msg=$event"
简写方式:在组件上使用v-model
value="msg"
@input="msg=$event"
注意:一个组件上只能使用一次v-model-->
<script type='text/javascript'>
//子组件既要使用数据也要修改数据
Vue.component('Father', {
template: `<div>
<h1>我是父组件的值{{msg}}</h1>
<hr/>
<son v-model="msg"></son>
</div>`,
data() {
return {
msg: "father~"
}
}
})
Vue.component('Son', {
template: `<div>
<h2>我是子组件</h2>
<span>接收父组件传值{{val}}</span>
<input ref="iptRef" type="text" @input="change">
</div>`,
model: {
prop: 'valueFather',
event: 'changeValue'
},
props: {
valueFather: {
required: true
}
},
data() {
return {
val: this.valueFather
}
},
methods: {
change(event) {
console.log(this.val)
this.$emit('changeValue', event.target.value)
//console.log(this.$refs.iptRef.value)
//this.$emit('input', this.$refs.iptRef.value)
}
}
})
var vm = new Vue({
el: '#app',
data: {}
});
</script>
</body>