众所周知,Vue 是基于组件来构建 web 应用的。组件将模块和组合发挥到了极致。Vue 是虽然说吸收了 AngularJs 的 MVVM的思想,可是它是单向数据流的,也就是说子组件没法直接改变父组件状态。下面总结出经常使用的组件消息传递的方式。html
该方式的数据传递是遵循 Vue 单向数据流的规则的,所以使用起来十分的天然。若父组件的数据改变子组件的 UI 展示也随之变化。
Parent.vuevue
<template> <div> <h1>Parent</h1> <child :name="childName" /> <button @click="changeChildName">change the child name</button> </div> </template> <script> import Child from './Child'; export default { components: { Child, }, data() { return { childName: 'child name is what?', }; }, methods: { changeChildName() { this.childName = 'no name'; }, }, }; </script>
Child.vuereact
<template> <div>{{name}}</div> </template> <script> export default { props: ['name'], }; </script>
效果以下:git
这里介绍两种方式:
一、子组件触发事件,父组件监听事件作出数据改变
二、父组件将数据变动方法以 props 的形式传给子组件(借鉴 react 的父子通讯方式)github
父组件上经过 v-on 监听子组件所触发的事件。
EventParent.vueweb
<template> <div> <h1>Event Parent</h1> <child :name="childName" @changeParent="changeChildName" /> </div> </template> <script> import Child from './Child'; export default { components: { Child, }, data() { return { childName: 'child name is what?', }; }, methods: { changeChildName() { this.childName = 'no name'; }, }, }; </script>
EventChild.vue编程
<template> <div> {{name}} <button @click="changeParentData">change the parent name</button> </div> </template> <script> export default { props: ['name'], methods: { changeParentData() { this.$emit('changeParent'); }, }, }; </script>
效果如图:小程序
由于本身写 react 较多,因此好奇 Vue 是否支持子组件回调父组件的事件处理函数,试了一下是能够的。好像 Element UI 使用该方式较多。我的认为该方法和事件方式一样灵活。
Parent.vue浏览器
<template> <div> <h1>Props Parent</h1> <child :name="childName" :changeName="changeChildName" /> </div> </template> <script> import Child from './Child'; export default { components: { Child, }, data() { return { childName: 'child name is what?', }; }, methods: { changeChildName() { this.childName = 'no name'; }, }, }; </script>
Child.vue编程语言
<template> <div> <div>{{name}}</div> <button @click="changeName">Change Name</button> </div> </template> <script> export default { props: ['name', 'changeName'], }; </script>
以 props 的这种方式你们能够尝试实现一下是一种新的思路。
上述三个实例都在讲述父子组件的通讯,那么不相关的组件该如何通讯呢?能够建立一个 Vue 的实例做为桥
来中转事件。
eventHub.js
import Vue from 'vue'; export default new Vue();
Child01.vue
<template> <div> <div>我是哥哥,我来触发事件</div> <button @click="clickButton">CLICK</button> </div> </template> <script> import EventHub from './eventHub'; export default { methods: { clickButton() { EventHub.$emit('emitevent'); }, }, }; </script>
Child02.vue
<template> <div> <div>我是弟弟,我来监听哥哥触发的事件来改变本身的数据</div> <span>{{title}}</span> </div> </template> <script> import EventHub from './eventHub'; export default { created() { EventHub.$on('emitevent', () => { this.title = 'Hi Brother'; }); }, data() { return { title: 'Hello EveryOne~', }; }, }; </script>
效果如图:
父组件改变子组件的数据利用正常单向数据流的特性便可,子组件改变父组件的数据能够经过事件或者函数 props 两种方式实现,非父子组件通讯则利用 EventHub 中转一下。
欢迎你们指正批评、或留言。QQ群:538631558
【开发环境推荐】 Cloud Studio 是基于浏览器的集成式开发环境,支持绝大部分编程语言,包括 HTML五、PHP、Python、Java、Ruby、C/C++、.NET 小程序等等,无需下载安装程序,一键切换开发环境。 Cloud Studio提供了完整的 Linux 环境,而且支持自定义域名指向,动态计算资源调整,能够完成各类应用的开发编译与部署。