1. props / $emit
父组件传递值,子组件通过props接收。
子组件向父组件传值,子组件通过$emit发送。
// 父组件
<template>
<div id="app">
<Child :users="users" @change="change"></Child>// 将父组件的data传到子组件,将子组件中的change方法接收
<a @click="add">点击添加成员</a>
</div>
</template>
<script>
import Child from "./components/Users"
export default {
name: 'App',
data(){
return{
users:["a","b","c"]
}
},
components:{
Child
},
methods:{
change:function(reslut){
console.log(reslut)
}
}
}
// Child子组件
<template>
<div class="hello">
<ul>
<li v-for="item in userList">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'child',
//子组件通过props来接收父组件传递来的方法
//props:['users'] //不对接收的值做处理
props:{ //对接收的值做处理
users:{
type:Array,
required:true
}
},
data(){
userList: users
},
methods:{
add:function(){
userList.pusth('d');
this.$emit('change', userList); //自定义事件,通过$emit发送事件,同时传递参数值。 }
}
}
</script>
2. $refs
ref 加在子组件上,用this.$refs.ref值,获取到的是组件实例,可以使用组件的所有方法。在使用方法时直接this. $refs.ref值.方法()就可以使用了。
// 父组件
<template>
<div id="app">
<Child ref='childRef'></Child>// 父组件中通过ref来使用子组件中的方法
<button @click='ParentMethod'></button>// 点击按钮时触发子组件中的childMethod方法
</div>
</template>
<script>
import Child from "./components/Users"
export default {
name: 'App',
components:{
Child
},
methods:{
ParentMethod(){
this.$refs.childRef.childMethod() //输出'我是子组件中的方法'
}
}
}
//子组件
<template>
<div class="hello">
</div>
</template>
<script>
export default {
name: 'child',
methods:{
childMethod(){
console.log('我是子组件中的方法')
}
}
}
</script>
3. provide / inject
Vue2.2.0新增API,这对选项需要一起使用,以允许一个祖先组件(provider)向其所有子孙后代(inject)注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
// A.vue
export default {
provide: {
name: 'baby'
}
}
// B.vue
export default {
inject: ['name'],
mounted () {
console.log(this.name); // baby
}
}
需要注意的是:provide和 inject绑定并不是可响应的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的
所以,上面 A.vue 的 name
如果改变了,B.vue 的 this.name
是不会改变的,仍然是 baby。
4. $parent / $children
this. p a r e n t 可以直接访问该组件的父实例或组件;父组件也可以通过 t h i s . parent 可以直接访问该组件的父实例或组件;父组件也可以通过this. parent可以直接访问该组件的父实例或组件;父组件也可以通过this.children 访问它所有的子组件;
需要注意 $children 并不保证顺序,也不是响应式的。
//父组件
<template>
<div>
<testVue></testVue>
<button @click="clickChild">$children方式获取子组件值</button>
</div>
</template>
<script>
import testVue from './test'
export default {
data(){
return {
total: 108
}
},
components: {
testVue
},
methods: {
funa(e){
console.log("index",e)
},
clickChild(){
console.log(this.$children[0].msg); //通过$children获取子组件的data
}
}
}
</script>
//子组件
<template>
<div>
<button @click="parentClick">点击访问父组件</button>
</div>
</template>
<script>
export default {
data(){
return {
msg:"我是子组件中的data"
}
},
methods: {
parentClick(){
this.$parent.funa("我在子组件中调用父组件的方法") //通过$parent获取父组件的方法
console.log(this.$parent.total); //通过$parent获取父组件的data
}
}
}
</script>
5. $EventBus
eventBus 适合小项目、数据被更少组件使用的项目,对于中大型项目数据在很多组件之间使用的情况 eventBus 就不太适用了。
eventBus 其实就是一个发布订阅模式,利用 Vue 的自定义事件机制,在触发的地方通过 $emit 向外发布一个事件,在需要监听的页面,通过 $on 监听事件。
import Vue from 'vue'
//因为是全局的一个'仓库',所以初始化要在全局初始化
const EventBus = new Vue()
//在已经创建好的Vue实例原型中创建一个EventBus
Vue.prototype.$EventBus = new Vue()
<!-- A.vue -->
<template>
<div>
<button @click="sendMsg">发送MsgA</button>
</div>
</template>
<script>
export default {
data(){
return{
MsgA: 'A组件中的Msg'
}
},
methods: {
sendMsg() {
/*调用全局Vue实例中的$EventBus事件总线中的$emit属性,发送事件"aMsg",并携带A组件中的Msg*/
this.$EventBus.$emit("aMsg", this.MsgA);
}
}
};
</script>
<!-- B.vue -->
<template>
<div>
<p>{{msgB}}</p>
</div>
</template>
<script>
export default {
data(){
return {
msgB: ''
}
},
mounted() {
/*调用全局Vue实例中的$EventBus事件总线中的$on属性,监听A组件发送到事件总线中的aMsg事件*/
this.$EventBus.$on("aMsg", (data) => {
//将A组件传递过来的参数data赋值给msgB
this.msgB = data;
});
}
};
</script>