基于vue的配置项透传组件的设计方案

935 阅读2分钟

设计之初需要实现的功能

  1. 如何在外部 store 生成唯一的变量 key。
  2. key 对应值的修改需要和组件实现联动。
  3. 组件如何从 store 中获得自己的配置项

业务场景

目前的常规组件实现如下图

通常是由 n 个组件组成一个 root 组件(组件的划分通常是为了逻辑封装或者复用

而我们的配置项,可能是在 root 组件和 A、B、C 组件中使用,此时,我们需要怎样不通过 Props 形式完成与外部独立store的关联呢?

存在的问题

  1. 如果使用vuex的形式,我们需要先定义 module 在定义 commit ,再定义getter。最大的问题是,这一步声明,是需要明确 key-value 映射的,而我们的A组件可不仅仅只会出现当前root组件内,这要如何区分不同root组件中的A组件?
  2. 如何区分root组件的两个 A 组件?

解决方式

  1. 根据组件嵌套,生成key-value映射

缺陷:必须在渲染阶段,才能知道key-value的映射关系,无法在编译前进行优化。

方法实现

  1. 获取组件嵌套关系

    const currentPath =
       (vm.$vnode &&
         vm.$vnode.key &&
         `${vm.$options._componentTag}_${vm.$vnode.key}`) ||
       vm.$options._componentTag;
    

    vm 是当前的 vue 实例,我们通过拼接 key 以及 _componentTag 递归向上寻父组件,可以获得当前组件的唯一嵌套关系。

  2. 将变量名与组件嵌套路径进行拼接,生成唯一的 key

eg. 譬如,我们要需改 root.A_1.title(A 组件中的 title 变量),
我们在外部 store 中的注册 key 就是 root.A_1.title;
而另外一个A组件的 title 则为 root.A_2.title。
B组件的title则为 root.B_1.title。
  1. 如何将变量与视图进行绑定。

外部的 store ,我使用一个 vue 实例进行依赖更新。绑定在该store中的任何一个变量,都会转化为 get/set 进行依赖收集因此,在组件中使用,我们需要通过computed的形式使用,触发变量使用时的视图更新。

computed: {
    ...mapPathToComputed([{
        key: "title",
        build_component: "fontConfig",
      }])
}
// 使用的话,就是基本的计算属性用法。
this.title

mapPathToComputed 包装函数,承载了在外部 store 中注册以及从外部 sotore 中取值的逻辑实现,返回一个 function[ ]

注:computed 是惰性求值的。

  1. 进行持久化操作的话,就是该 store 的实例化的过程