自定义组件/插件/Plugin 原理概览

举例 鲁班H5 轮播图组件

  • 这个组件本质上就是一个 vue 组件
  • 其本质是对 Vant组件库的轮播组件 的简单封装
  • 核心代码

    • 可以看出来,核心代码其实非常简单,和大家平时写轮播图,或者调用第三方组件库的轮播图的方式几乎没有区别,基本上是配置一些 props,比如轮播间隔时间、轮播图列表等
    • 接下来我们来讲一下不同的地方在哪里🧐

自定义组件和常规组件的不同之处(影响多个属性)

如下这段代码为例,相信写 vue 或者 react 的同学,应该会比较熟悉

配置 轮播组件的 items,也就是轮播的选项信息

  1. props: {
  2. items: {
  3. type: Array,
  4. default: () => [
  5. { value: 'https://img.yzcdn.cn/vant/apple-1.jpg' },
  6. { value: 'https://img.yzcdn.cn/vant/apple-2.jpg' }
  7. ],
  8. // 主要区别应该是这里
  9. editor: {
  10. custom: true
  11. }
  12. }
  13. }
  • 这里和我们平时写的组件是有些区别的,我们添加了这些信息
  1. editor: {
  2. custom: true
  3. }
  • 其中custom: true 表示在编辑器的右侧面板,采用自定义属性编辑器来配置自定义组件的相关属性

  • 在这里可以理解为:采用自定义属性编辑器来配置轮播组件items属性

  • 那么,它和上面的 按钮组件的 color.editor 有什么区别呢?为何这里不采用一个第三方组件呢?

  • 答案:因为有时候,有些操作会影响多个属性值(联动)

  • 以轮播图组件的实际场景为例,我们来解释下什么叫:有些操作会影响多个属性值。毕竟这句话猛的一听,有点像教科书,晦涩难懂,咱还是说说实际业务场景吧

有图有真相:
原理篇:多属性自定义编辑器 - 图1

  • 按照图中的说法,如果我们点击了【减号】按钮,其实就会影响到两个属性:activeIndexitems,因此如果写了一个和上面的颜色选择器一样的组件,放在 activeIndex 或 items 任意一方中都是不太合适的,因为这个算是二者共有的;

    • 轮播图 props 主要代码如下:代码链接
      1. props: {
      2. activeIndex: {
      3. type: Number,
      4. default: 0,
      5. editor: {
      6. custom: true
      7. }
      8. },
      9. items: {
      10. type: Array,
      11. default: () => [
      12. { value: 'https://img.yzcdn.cn/vant/apple-1.jpg' },
      13. { value: 'https://img.yzcdn.cn/vant/apple-2.jpg' }
      14. ],
      15. editor: {
      16. custom: true
      17. }
      18. }
      19. }
  • 如何解决呢:

    • 还记得我们上面讲过的,将按钮 放置到 中间画布上的操作吗?
      鲁班会自动遍历按钮组件props,构造一个包含了组件基本属性和其默认值的配置对象:pluginProps

    • 我们可以写一个组件,比如叫 slideEditor (轮播编辑器,叫啥随你,最好有相关性,清晰易懂即可,最好加注释)

    • 我们要解决的问题是,点击一个按钮,会修改多个属性的值,多个属性的值和其值存在哪里呢?其实就在 pluginProps

    • 我们把 pluginProps 作为属性传入到 slideEditor(也就说将轮播图组件的所有 props和其值 都传入到 slideEditor 中),这样就可以在 slideEditor 中更新这个 pluginProps 了,换句话说,所有的 props和值都给你了,你可以改多个 props 的值了

    • show me the code,让我们看下 slideEditor 是如何实现的吧,主要代码如下:完整代码链接

  1. <!--
  2. 轮播组件属性自定义编辑器(增强编辑器)
  3. 文档:https://github.com/luban-h5/vue-cli-plugin-lbhc/wiki
  4. -->
  5. <template>
  6. <div>
  7. <a-pagination
  8. :current="current"
  9. @change="handleSelectPage"
  10. size="small"
  11. :total="innerItems.length"
  12. :defaultPageSize="1"
  13. :itemRender="itemRender"
  14. />
  15. <lbs-image-gallery
  16. style="margin: 16px 0"
  17. :value="currentItem.value"
  18. @change="handleSelectImage"
  19. />
  20. </div>
  21. </template>
  22. <script>
  23. export default {
  24. props: {
  25. /**
  26. * 通过 new Vue.component('plugin-name').$optioins.props 收集组件的属性
  27. * 作为 Object,传递给 props editor,从而从过属性自定义编辑器 来更新属性值
  28. */
  29. pluginProps: {
  30. type: Object,
  31. default: () => ({
  32. items: [],
  33. activeIndex: 0
  34. })
  35. }
  36. },
  37. methods: {
  38. itemRender (current, type, originalElement) {
  39. // 减号按钮
  40. if (type === 'prev') {
  41. return <a-button style={{ marginRight: '8px' }} size="small" icon="minus" onClick={() => this.minus(current)} disabled={this.innerItems.length === 1}></a-button>
  42. } else if (type === 'next') {
  43. return <a-button style={{ marginLeft: '8px' }} size="small" icon="plus" onClick={this.add}></a-button>
  44. }
  45. return originalElement
  46. },
  47. // 点击减号的 callback:items.splice 和 activeIndex--
  48. minus (index) {
  49. if (this.innerItems.length === 1) return
  50. this.pluginProps.items.splice(index, 1)
  51. this.pluginProps.activeIndex = Math.max(index - 1, 0)
  52. }
  53. }
  54. }
  55. </script>

大概的原理到这里就差不多,这也是鲁班H5的自定义组件和其编辑器的核心原理了

下一章来讲讲,如何利用鲁班H5 官网提供的自定义组件-脚手架快速开发自定义组件