前言
一般来说,组件可以有以下几种关系:
#1.父子组件之间的通信
在 Vue.js 中,父子组件的关系可以总结为 props down, events up 。父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。看看它们是怎么工作的。
#1.1 父组件到子组件使用props传递数据
prop 是父组件用来传递数据的一个自定义属性。子组件需要显式地用 props 选项 声明 “prop”:
Vue.component('child', {
// 声明 props
props: ['message'],
// 就像 data 一样,prop 可以用在模板内
// 同样也可以在 vm 实例中像 “this.message” 这样使用
template: '<span>{{ message }}</span>'
})
父组件中使用子组件并传值给子组件:
<child message="hello!"></child>
单向数据流
prop 是单向绑定的:当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态。 另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。
注意:JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。
#1.2 子组件到父组件使用自定义事件
-
使用 $on(eventName) 监听事件
-
使用 $emit(eventName) 触发事件
父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。然后再对应子组件方法执行处触发事件,两者缺一不可。
<!-- 父组件 -->
<div id="app">
<!-- 子组件 -->
<!-- 父组件直接用 v-on 来监听子组件触发的事件。 -->
<!-- 需跟子组件中的$emit组合使用 -->
<mycon v-on:son_method="father_method"></mycon>
</div>
// 子组件
Vue.component('mycon', {
template: '<button v-on:click="son_method">子按钮</button>',
methods: {
// 按钮点击时候触发事件
son_method: function () {
this.counter += 1;
console.log("son");
// 这句话来触发事件
// 必须跟模板中的v-on配合使用
this.$emit('son_method');
}
},
});
// 父组件
new Vue({
el: "#app",
methods: {
father_method: function () {
console.log("father");
}
}
});
#1.3 provide/inject
一句话概括:祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。
// Parent.vue
export default {
provide: {
name: 'hello,chrischeng!'
}
}
// Child.vue
export default {
inject: ['name'],
mounted () {
console.log(this.name); // hello,chrischeng!
}
}
需要注意的是:provide 和 inject 绑定并不是可响应的。不过,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。 所以,上面 Parent.vue 的 name 如果改变了,Child.vue 的 this.name 是不会改变的,仍然是 hello,chrischeng! 。
#1.4 $parent / $children与 ref
ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
$parent / $children:访问父 / 子实例
// Child.vue
export default {
data () {
return {
title: 'Vue.js'
}
},
methods: {
sayHello () {
window.alert('Hello');
}
}
}
// Parent.vue
<template>
<child ref="cc"></child>
</template>
<script>
export default {
mounted () {
const cc= this.$refs.cc;
console.log(cc.title); // Vue.js
cc.sayHello(); // 弹窗
}
}
</script>
#2 非父子组件之间的通信 Event Bus
在简单的场景下,使用一个空的 Vue 实例作为中央事件总线:
var bus = new Vue()
// 触发组件 A 中的事件(发布消息)
bus.$emit('id-selected', 1)
// 在组件 B 创建的钩子中监听事件(订阅消息)
bus.$on('id-selected', function (id) {
// ...
})
#3 状态管理(vuex).
vue的具体原理和使用方法参照官方文档就可以了; vuex
当你需要开发的系统比较小型的,vuex用不用都行;但是,一旦你的项目规模比较大,这里强烈推荐使用vuex
需要注意的是: vuex使用要合理,要避免滥用,造成一些不必要的麻烦