扩展 Inspector

有时候我们需要对自己书写的 Component 定义一份 Inspector,用自定义的方式对他进行显示。这个时候 我们可以考虑对 Inspector 进行扩展。

扩展的步骤如下:

  1. 在 Component 中注明自定义 Inspector 的入口文件
  2. 创建自定义 Inspector 的扩展包
  3. 在扩展包中编写自定义 Inspector 的入口文件

在 Component 中注明自定义 Inspector 的入口文件

首先我们需要定义一份 Component 脚本,并且为这个脚本注明使用自定义 Inspector,方法如下:

cc.Class({
  name: 'Foobar',
  extends: cc.Component,
  editor: {
    inspector: 'packages://foobar/inspector.js',
  },
  properties: {
    foo: 'Foo',
    bar: 'Bar'
  },
});

注意1: 这里我们定义了一个 editor 字段,并在该字段中定义了 inspector 入口文件。

注意2:inspector 中我们采用 packages:// 协议定义入口文件路径。在 Cocos Creator 中会对 packages:// 协议做特殊处理,会将 packages:// 协议后面的分路径名当做扩展包名字进行搜索, 并根据搜索结果将整个协议替换成扩展包的路径做后续搜索。

创建自定义 Inspector 的扩展包

和我们创建一份扩展包没有任何区别,你可以按照 你的第一个扩展包 中的 方式创建一份。这里我们假设我们的扩展包名为 foobar。

注意,在创建完扩展包后,你需要重启一下 Cocos Creator 以便让他正确读入该扩展包。

在扩展包中编写自定义 Inspector 的入口文件

接下来我们就可以在 foobar 包中定义 inspector.js

Vue.component('foobar-inspector', {
  template: `
    <ui-prop v-prop="target.foo"></ui-prop>
    <ui-prop v-prop="target.bar"></ui-prop>
  `,

  props: {
    target: {
      twoWay: true,
      type: Object,
    },
  },
});

Cocos Creator 的 Inspector 扩展使用了 Vue。这里我们通过定义一份 Vue 的组件,并在组件中定义 props,使得其包含 target 数据来完成整个 Inspector 的数据定义。

target 就是我们的 Foobar Class 在 Inspector 中对应的实例。

关于 target

上一小节中提到的 target 实例是经过 Inspector 处理过的 target。其内部包含了对属性的加工处理。 在使用的时候,我们不能简单的认为 target.foo 就代表 foo 的值。如果你去查看 target.foo 你会 发现他是一个 Object 而不是我们在最开始定义的那样一个 'Foo' 的字符串。该份 Object 中包含了 attrstypevalue 等信息。其中的 value 才是我们真正的值。

这么做的目的是为了让 Inspector 可以更好的获得数据可视化的各方面信息。例如当你定义了 cc.Class 的属性为:

properties: {
  foo: {
    value: 'Foo',
    readonly: true
  }
}

这个时候在 Inspector 中的 target 里反应出的信息为 target.foo.value 为 'Foo',target.foo.attrs.readonlytrue。 这些信息有助于帮助你创建多变的界面组合。

关于属性绑定

由于这些信息非常繁琐,Cocos Creator 也对 Vue 的 directive 做了一定的扩展。目前我们扩展了 v-propv-value v-readonlyv-disable

当你还是想利用 Cocos Creator 的默认方案显示数据段时,你可以使用 v-prop 配合 <ui-prop> 控件做绑定,如:

<ui-prop v-prop="target.foo"></ui-prop>

当你想使用 <ui-xxx> 的原生控件时,你可以使用 v-value 来做数据绑定,如:

<ui-input v-value="target.foo.value"></ui-input>

当你想对控件应用 readonly 或者 disable 行为时,请使用 v-readonlyv-disable。如:

<ui-button v-readonly="target.foo.attrs.readonly">Foo</ui-button>
<ui-button v-disable="target.bar.value">Bar</ui-button>