JianghuJS-组件化开发与通信

12002

1、特点

JianghuJS 使用 Vue.js 作为主要的前端框架,通过 Vue.js 提供的组件化开发能力来构建前端应用。Vue.js 是一款现代化的 JavaScript 框架,专注于构建用户界面,它的核心思想是组件化开发,使得前端代码更易于维护和扩展。

在 Vue.js 中,一个组件通常由一个 Vue 实例构成,具有自己的模板、样式和逻辑。这种组件化的开发方式使得前端代码可以按照功能划分成小块,每个小块都可以独立开发和测试。Vue.js 提供了一些机制来实现组件之间的通信、状态管理等功能,使得整个前端应用可以有机地组织在一起。

  • 为什么要组件化

    在JianghuJS中,组件化开发具有重要意义,原因如下:

    • 模块化设计: 每个组件都被设计成相对独立、可复用的模块,有助于代码的模块化,提高代码的可维护性和可重用性。

    • 解耦合: 组件之间通过定义清晰的接口进行通信,从而实现了组件之间的解耦合。每个组件只关注自己的业务逻辑,不依赖于其他组件的内部实现细节。

    • 团队协作: 每个组件可以由不同的团队或开发者负责,通过清晰的接口和规范,实现了模块的独立开发,有助于提高团队的协作效率。

    • 可维护性: 组件独立开发和维护,当系统需要更新或修复时,只需关注特定组件的代码,减少了影响范围,提高了代码的可维护性。

    • 快速开发: 组件化使得可以快速搭建应用,通过组合现有的组件,而不是从头开始开发每一个功能,加速了开发进程。

  • 组件化开发的优点

    • 代码复用:Vue.js的组件可以被多次使用,提高了代码的复用率。将页面划分为多个组件,可以让不同的组件处理不同的逻辑,使得代码更具可读性,易于维护和升级。

    • 组件化的思想:Vue.js采用的是组件化的思想。将一个大的应用拆分成多个小的组件,让不同的组件互相不干扰,可以更加方便的进行开发和升级。同时,这样的设计也可以提高代码的重用性、可维护性和可扩展性。

    • 数据传递:Vue.js采用的是单向数据流的方式,将数据从父组件传递给子组件或者将子组件的数据传递给父组件。这种数据流的方式,让组件之间的状态更加清晰和可控,避免了数据混乱和错误的发生。

    • 视图控制:Vue.js中的组件可以包含自己的内部状态和逻辑,以封装视图上的交互和处理行为。这样的设计可以让开发人员专注于组件的设计和UI的实现,而不用关注系统的其他部分。

JianghuJS 利用 Vue.js 的组件化开发能力,通过定义各种业务组件,构建了一套灵活、可扩展的前端框架。这样的框架能够适应不同项目的需求,同时提供了一致的开发风格和标准,有助于提高开发效率和代码的可维护性。

2、通信方式

  • 父子组件通信

可以通过父组件向子组件传递 props 数据来实现,子组件通过 props 接收数据即可。此外,子组件向父组件传递数据的方式有:使用自定义事件和 emit/on 方法、使用回调函数等方法

  1. // 父组件
  2. <template>
  3. <div>
  4. <child :msg="parentMsg"/>
  5. </div>
  6. </template>
  7. <script>
  8. import Child from './Child.vue'
  9. export default {
  10. name: 'Parent',
  11. components: { Child },
  12. data () {
  13. return {
  14. parentMsg: 'Hello'
  15. }
  16. }
  17. }
  18. </script>
  19. // 子组件
  20. <template>
  21. <div>{{msg}}, Child Component</div>
  22. </template>
  23. <script>
  24. export default {
  25. name: 'Child',
  26. props: {
  27. msg: String
  28. }
  29. }
  30. </script>

接收数据:在子组件中通过 props 接收父组件的数据

  1. // 子组件
  2. <template>
  3. <div>{{msg}}, Child Component</div>
  4. </template>
  5. <script>
  6. export default {
  7. name: 'Child',
  8. props: {
  9. msg: String
  10. }
  11. }
  12. </script>
  • 兄弟组件通信

可以使用父组件作为中转站,通过向父组件传递数据,由父组件再向另一个需要通信的子组件传递数据。除此之外,还可以使用 EventBus、Vuex 等 Vue.js 提供的全局状态管理工具实现组件之间的通信。

EventBus通信:

  1. // EventBus.js
  2. import Vue from 'vue'
  3. export default new Vue()
  4. // ComponentA.vue
  5. <template>
  6. <div>
  7. <h2>Component A</h2>
  8. <button @click="onClick">Send Data</button>
  9. </div>
  10. </template>
  11. <script>
  12. import EventBus from '@/utils/EventBus'
  13. export default {
  14. name: 'ComponentA',
  15. methods: {
  16. onClick () {
  17. EventBus.$emit('event-name', 'Component A sends data')
  18. }
  19. }
  20. }
  21. </script>
  22. // ComponentB.vue
  23. <template>
  24. <div>
  25. <h2>Component B</h2>
  26. <div>{{msg}}</div>
  27. </div>
  28. </template>
  29. <script>
  30. import EventBus from '@/utils/EventBus'
  31. export default {
  32. name: 'ComponentB',
  33. data () {
  34. return {
  35. msg: ''
  36. }
  37. },
  38. mounted () {
  39. EventBus.$on('event-name', data => {
  40. this.msg = data
  41. })
  42. }
  43. }
  44. </script>
  • 跨级组件通信

可以使用 provide/inject API,它们可以向下传递数据,被注入的组件可以通过 inject 属性来接收数据。在注入属性中指定一个键名后,可以在被注入的组件中使用相同键名来访问这个属性

  1. // 祖先组件
  2. <template>
  3. <div>
  4. <parent-component />
  5. </div>
  6. </template>
  7. <script>
  8. import ParentComponent from './ParentComponent.vue'
  9. export default {
  10. name: 'AncestorComponent',
  11. components: { ParentComponent },
  12. provide () {
  13. return {
  14. ancestorMsg: 'I am ancestor component!'
  15. }
  16. }
  17. }
  18. </script>
  19. // 父级组件
  20. <template>
  21. <div>
  22. <child-component />
  23. </div>
  24. </template>
  25. <script>
  26. import ChildComponent from './ChildComponent.vue'
  27. export default {
  28. name: 'ParentComponent',
  29. components: { ChildComponent }
  30. }
  31. </script>
  32. // 子组件
  33. <template>
  34. <div>
  35. {{injectMsg}}, ChildComponent
  36. </div>
  37. </template>
  38. <script>
  39. export default {
  40. name: 'ChildComponent',
  41. inject: ['ancestorMsg'],
  42. data () {
  43. return {
  44. injectMsg: this.ancestorMsg
  45. }
  46. }
  47. }
  48. </script>