适配array

This commit is contained in:
xuyanfeng 2021-06-15 22:19:47 +08:00
parent 9540b78e90
commit 5558c6fe71
3 changed files with 221 additions and 150 deletions

View File

@ -28,10 +28,17 @@ export class TextData extends Info {
} }
export class ArrayData extends Info { export class ArrayData extends Info {
data: Array<Property> = [];
constructor() { constructor() {
super(); super();
this.type = DataType.Array; this.type = DataType.Array;
} }
add(info: Property) {
this.data.push(info);
return this;
}
} }
export class ObjectData extends Info { export class ObjectData extends Info {

View File

@ -255,7 +255,7 @@ class CCInspector {
return null; return null;
} }
_genInfoData(node: any, key: string, path: any) { _genInfoData(node: any, key: string, path: Array<string>) {
let propertyValue = node[key]; let propertyValue = node[key];
let info = null; let info = null;
switch (typeof propertyValue) { switch (typeof propertyValue) {
@ -277,6 +277,13 @@ class CCInspector {
info = new ColorData(`#${hex}`); info = new ColorData(`#${hex}`);
} else if (Array.isArray(propertyValue)) { } else if (Array.isArray(propertyValue)) {
info = new ArrayData(); info = new ArrayData();
for (let i = 0; i < propertyValue.length; i++) {
let propPath = path.concat(i.toString());
let itemData = this._genInfoData(propertyValue, i.toString(), propPath);
if (itemData) {
info.add(new Property(i.toString(), itemData));
}
}
} else if (propertyValue instanceof Object) { } else if (propertyValue instanceof Object) {
!info && (info = this._buildVecData({ !info && (info = this._buildVecData({
// @ts-ignore // @ts-ignore

View File

@ -1,80 +1,102 @@
<template> <template>
<div id="ui-prop"> <div id="ui-prop">
<div @mousedown="onPropNameMouseDown" class="key"> <div class="normal-data" style="display: flex;flex-direction: row;align-items: center;min-height: 30px;margin: 0;">
<div class="text">{{ name }}</div> <div @mousedown="onPropNameMouseDown" class="key"
</div> :style="{'margin-left':indent*10+'px'}">
<div class="value"> <i class=" data-arrow"
<el-input v-if="isString()" v-model="value.data" v-if="arrow"
:disabled="value.readonly" :class="fold?'el-icon-caret-right':'el-icon-caret-bottom'"
@change="onChangeValue"> :style="{'visibility':isArray()?'visible':'hidden'}"
</el-input> @click="onClickFold"></i>
<el-input v-if="isText()" <div class="text">{{ name }}</div>
type="textarea"
:autosize="{minRows:3,maxRows:5}"
placeholder="请输入内容"
:disabled="value.readonly"
@change="onChangeValue"
v-model="value.data">
</el-input>
<el-input-number v-if="isNumber()"
style="width: 100%;text-align: left"
v-model="value.data"
:step="step"
:disabled="value.readonly"
@change="onChangeValue"
controls-position="right"
></el-input-number>
<div v-if="isVec2()||isVec3()" class="vec">
<ui-prop v-for="(vec, index) in value.data"
:key="index"
:value="vec.value"
:name="vec.name">
</ui-prop>
</div> </div>
<el-select v-model="value.data" <div class="value">
:disabled="value.readonly" <el-input v-if="isString()" v-model="value.data"
v-if="isEnum()" style="width: 100%;" :disabled="value.readonly"
@change="onChangeValue"> @change="onChangeValue">
<el-option v-for="(opt, index) in value.values" </el-input>
:key="index" <el-input v-if="isText()"
:label="opt.name" type="textarea"
:value="opt.value"> :autosize="{minRows:3,maxRows:5}"
</el-option> placeholder="请输入内容"
</el-select> :disabled="value.readonly"
<el-checkbox v-model="value.data" @change="onChangeValue"
v-if="isBool()" v-model="value.data">
:disabled="value.readonly" </el-input>
@change="onChangeValue"> <el-input-number v-if="isNumber()"
</el-checkbox> style="width: 100%;text-align: left"
<div class="color" v-if="isColor()"> v-model="value.data"
<el-color-picker style="position: absolute;" :step="step"
:disabled="value.readonly" :disabled="value.readonly"
v-model="value.data" @change="onChangeValue"> @change="onChangeValue"
</el-color-picker> controls-position="right"
<div class="hex" :style="{color:colorReverse(value.data)}">{{ value.data }}</div> ></el-input-number>
</div>
<div v-if="isArrayOrObject()" class="array-object"> <div v-if="isVec2()||isVec3()" class="vec">
<div class="text"> <ui-prop v-for="(vec, index) in value.data"
{{ valueString() }} :key="index"
:arrow="false"
:value="vec.value"
:name="vec.name">
</ui-prop>
</div> </div>
<el-button @click="onShowValueInConsole">log</el-button> <el-select v-model="value.data"
</div> :disabled="value.readonly"
<div v-if="isImage()" class="image-property"> v-if="isEnum()" style="width: 100%;"
<el-popover v-if="isImage()" placement="top" trigger="hover"> @change="onChangeValue">
<div <el-option v-for="(opt, index) in value.values"
style="width: 100%;height: 100%;display: flex;flex-direction: row;align-items: center;justify-content: center;"> :key="index"
<img :src="value.data" alt="图片" style="max-width: 100px;max-height: 100px;object-fit: contain;"> :label="opt.name"
:value="opt.value">
</el-option>
</el-select>
<el-checkbox v-model="value.data"
v-if="isBool()"
:disabled="value.readonly"
@change="onChangeValue">
</el-checkbox>
<div class="color" v-if="isColor()">
<el-color-picker style="position: absolute;"
:disabled="value.readonly"
v-model="value.data" @change="onChangeValue">
</el-color-picker>
<div class="hex" :style="{color:colorReverse(value.data)}">{{ value.data }}</div>
</div>
<div v-if="isArray()" style="display: flex;flex-direction: column;">
{{ value.data.length }}
</div>
<!-- <div v-if="isArrayOrObject()" class="array-object">-->
<!-- <div class="text">-->
<!-- {{ valueString() }}-->
<!-- </div>-->
<!-- <el-button @click="onShowValueInConsole">log</el-button>-->
<!-- </div>-->
<div v-if="isImage()" class="image-property">
<el-popover v-if="isImage()" placement="top" trigger="hover">
<div
style="width: 100%;height: 100%;display: flex;flex-direction: row;align-items: center;justify-content: center;">
<img :src="value.data" alt="图片" style="max-width: 100px;max-height: 100px;object-fit: contain;">
</div>
<img :src="value.data" slot="reference" style="height: 36px;" alt="图片">
</el-popover>
<div style="flex:1;display: flex; flex-direction: row-reverse;">
<el-button @click="onShowValueInConsole">log</el-button>
</div> </div>
<img :src="value.data" slot="reference" style="height: 36px;" alt="图片"> </div>
</el-popover> <div class="slot">
<div style="flex:1;display: flex; flex-direction: row-reverse;"> <slot></slot>
<el-button @click="onShowValueInConsole">log</el-button>
</div> </div>
</div> </div>
<div class="slot"> </div>
<slot></slot> <div v-if="isArray()">
<div v-show="!fold" style="display: flex;flex-direction: column;">
<ui-prop v-for="(arr,index) in value.data"
:key="index"
:indent="indent+1"
:value="arr.value"
:name="'['+arr.name+']'">
</ui-prop>
</div> </div>
</div> </div>
</div> </div>
@ -96,6 +118,11 @@ export default class UiProp extends Vue {
@Prop({default: ""}) @Prop({default: ""})
name: string | undefined; name: string | undefined;
@Prop({default: 0})
indent!: number;
@Prop({default: true})
arrow!: boolean;
@Prop() @Prop()
value!: Info; value!: Info;
@ -136,6 +163,10 @@ export default class UiProp extends Vue {
return this.value && (this.value.type === DataType.Array || this.value.type === DataType.Object) return this.value && (this.value.type === DataType.Array || this.value.type === DataType.Object)
} }
isArray() {
return this.value && (this.value.type === DataType.Array)
}
isImage() { isImage() {
return this.value && (this.value.type === DataType.Image) return this.value && (this.value.type === DataType.Image)
} }
@ -143,6 +174,12 @@ export default class UiProp extends Vue {
created() { created() {
} }
private fold = false;
onClickFold() {
this.fold = !this.fold;
}
valueString() { valueString() {
try { try {
return JSON.stringify(this.value.data) return JSON.stringify(this.value.data)
@ -213,104 +250,124 @@ export default class UiProp extends Vue {
<style scoped lang="less"> <style scoped lang="less">
#ui-prop { #ui-prop {
margin: 0;
min-height: 30px; min-height: 30px;
overflow: hidden; margin: 0;
width: 100%;
display: flex; display: flex;
flex-direction: row; flex-direction: column;
align-items: center; justify-content: center;
.normal-data {
.key { margin: 0;
flex: 1; min-height: 30px;
float: left; overflow: hidden;
text-align: left; width: 100%;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
min-width: 90px;
.text {
user-select: none;
line-height: 30px;
font-size: 12px;
margin: 3px;
}
}
.value { .key {
flex: 3;
text-align: left;
height: 100%;
overflow: hidden;
min-width: 400px;
.color {
position: relative;
height: 30px;
.hex {
line-height: 30px;
position: relative;
text-align: center;
user-select: none;
pointer-events: none;
}
}
.vec {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
#ui-prop {
margin-top: 0;
margin-bottom: 0;
margin-right: 20px;
.value {
min-width: 100px;
}
.key {
min-width: 20px;
}
}
#ui-prop:last-child {
margin-right: 0;
}
}
.array-object {
flex: 1; flex: 1;
max-width: 100%; float: left;
overflow: hidden; text-align: left;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
min-width: 90px;
.data-arrow {
width: 20px;
height: 16px;
font-size: 16px;
cursor: pointer;
}
.text { .text {
flex: 1; user-select: none;
overflow: hidden; line-height: 30px;
white-space: nowrap; font-size: 12px;
text-overflow: ellipsis; margin: 3px;
} }
} }
.image-property { .value {
display: flex; flex: 3;
flex-direction: row; text-align: left;
align-content: center; height: 100%;
align-items: center; overflow: hidden;
height: 36px; min-width: 400px;
}
.slot { .color {
display: flex; position: relative;
width: 100%; height: 30px;
.hex {
line-height: 30px;
position: relative;
text-align: center;
user-select: none;
pointer-events: none;
}
}
.vec {
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
#ui-prop {
margin-top: 0;
margin-bottom: 0;
.normal-data {
.value {
min-width: 100px;
}
.key {
min-width: 20px;
}
#ui-prop:first-child {
margin-right: 20px;
}
#ui-prop:last-child {
margin-right: 0;
}
}
}
.array-object {
flex: 1;
max-width: 100%;
overflow: hidden;
display: flex;
flex-direction: row;
align-items: center;
.text {
flex: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.image-property {
display: flex;
flex-direction: row;
align-content: center;
align-items: center;
height: 36px;
}
.slot {
display: flex;
width: 100%;
}
}
} }
} }
} }