diff --git a/example/App.tsx b/example/App.tsx
index 76b027a..1715988 100644
--- a/example/App.tsx
+++ b/example/App.tsx
@@ -37,6 +37,9 @@ export default defineComponent({
const onActiveChange = (key: string) => {
state.activeKey = key;
+ if (!state.opened.includes(key)) {
+ state.opened.push(key);
+ }
};
return {
diff --git a/example/Basic.vue b/example/Basic.vue
index 9f1655b..4bfde82 100644
--- a/example/Basic.vue
+++ b/example/Basic.vue
@@ -18,6 +18,10 @@
+
@@ -44,9 +44,10 @@
@@ -85,7 +86,7 @@ const defaultData = {
};
export default defineComponent({
- name: 'SelectControl',
+ name: 'Editable',
components: {
VueJsonPretty,
},
@@ -95,7 +96,7 @@ export default defineComponent({
data: defaultData,
showLength: false,
showLine: true,
- showDoubleQuotes: true,
+ showLineNumber: false,
editable: true,
editableTrigger: 'click',
deep: 3,
diff --git a/example/SelectControl.vue b/example/SelectControl.vue
index 3a57111..87c551d 100644
--- a/example/SelectControl.vue
+++ b/example/SelectControl.vue
@@ -6,6 +6,10 @@
Options:
v-model:selectedValue:
{{ state.selectedValue }}
@@ -75,16 +75,17 @@
:data="state.data"
:path="state.path"
:deep="state.deep"
- :show-double-quotes="state.showDoubleQuotes"
+ :show-double-quotes="true"
:highlight-selected-node="state.highlightSelectedNode"
:show-length="state.showLength"
:show-line="state.showLine"
+ :show-line-number="state.showLineNumber"
:select-on-click-node="state.selectOnClickNode"
:collapsed-on-click-brackets="state.collapsedOnClickBrackets"
:path-selectable="(path, data) => typeof state.data !== 'number'"
:selectable-type="state.selectableType"
:show-select-controller="state.showSelectController"
- :custom-value-formatter="state.useCustomLinkFormatter ? customLinkFormatter : null"
+ :show-icon="state.showIcon"
@nodeClick="handleClick"
@selectedChange="handleChange"
/>
@@ -137,15 +138,15 @@ export default defineComponent({
showSelectController: true,
showLength: false,
showLine: true,
- showDoubleQuotes: true,
+ showLineNumber: false,
highlightSelectedNode: true,
selectOnClickNode: true,
collapsedOnClickBrackets: true,
- useCustomLinkFormatter: false,
path: 'res',
deep: 3,
itemData: {},
itemPath: '',
+ showIcon: false,
});
const handleClick = (path, data) => {
@@ -158,14 +159,6 @@ export default defineComponent({
// console.log('newVal: ', newVal, ' oldVal: ', oldVal);
};
- const customLinkFormatter = (data, key, path, defaultFormatted) => {
- if (typeof data === 'string' && data.startsWith('http://')) {
- return `
"${data}"`;
- } else {
- return defaultFormatted;
- }
- };
-
watch(
() => state.val,
newVal => {
@@ -192,18 +185,8 @@ export default defineComponent({
},
);
- watch(
- () => state.useCustomLinkFormatter,
- async () => {
- state.renderOK = false;
- await nextTick();
- state.renderOK = true;
- },
- );
-
return {
state,
- customLinkFormatter,
handleClick,
handleChange,
};
diff --git a/src/components/Tree/index.tsx b/src/components/Tree/index.tsx
index d2302a4..8774d0b 100644
--- a/src/components/Tree/index.tsx
+++ b/src/components/Tree/index.tsx
@@ -1,4 +1,12 @@
-import { defineComponent, reactive, computed, watchEffect, ref, PropType } from 'vue';
+import {
+ defineComponent,
+ reactive,
+ computed,
+ watchEffect,
+ ref,
+ PropType,
+ CSSProperties,
+} from 'vue';
import TreeNode, { treeNodePropsPass, NodeDataType } from 'src/components/TreeNode';
import { emitError, jsonFlatten, JSONDataType, cloneDeep } from 'src/utils';
import './styles.less';
@@ -54,6 +62,7 @@ export default defineComponent({
type: [String, Array] as PropType
,
default: () => '',
},
+ style: Object as PropType,
},
emits: ['nodeClick', 'bracketsClick', 'selectedChange', 'update:selectedValue', 'update:data'],
@@ -98,8 +107,9 @@ export default defineComponent({
if (startHiddenItem && startHiddenItem.path === item.path) {
const isObject = startHiddenItem.type === 'objectStart';
const mergeItem = {
- ...startHiddenItem,
...item,
+ ...startHiddenItem,
+ showComma: item.showComma,
content: isObject ? '{...}' : '[...]',
type: isObject ? 'objectCollapsed' : 'arrayCollapsed',
} as NodeDataType;
@@ -203,7 +213,6 @@ export default defineComponent({
const rootPath = props.path;
new Function('data', 'val', `data${path.slice(rootPath.length)}=val`)(newData, value);
emit('update:data', newData);
- console.log(newData);
};
watchEffect(() => {
@@ -240,6 +249,7 @@ export default defineComponent({
showDoubleQuotes,
showLength,
showLine,
+ showLineNumber,
showSelectController,
selectOnClickNode,
pathSelectable,
@@ -252,6 +262,7 @@ export default defineComponent({
editable,
editableTrigger,
showIcon,
+ style,
} = this;
const { onTreeNodeClick, onBracketsClick, onSelectedChange, onTreeScroll, onValueChange } =
@@ -271,6 +282,7 @@ export default defineComponent({
checked={selectedPaths.includes(item.path)}
selectable-type={selectableType}
show-line={showLine}
+ show-line-number={showLineNumber}
show-select-controller={showSelectController}
select-on-click-node={selectOnClickNode}
path-selectable={pathSelectable}
@@ -293,7 +305,12 @@ export default defineComponent({
'vjs-tree': true,
'is-virtual': virtual,
}}
- onScroll={virtual ? onTreeScroll: undefined}
+ onScroll={virtual ? onTreeScroll : undefined}
+ style={
+ showLineNumber
+ ? { paddingLeft: `${Number(flatData.length.toString().length) * 12}px`, ...style }
+ : style
+ }
>
{virtual ? (
diff --git a/src/components/TreeNode/index.tsx b/src/components/TreeNode/index.tsx
index b799de5..65cd253 100644
--- a/src/components/TreeNode/index.tsx
+++ b/src/components/TreeNode/index.tsx
@@ -42,6 +42,10 @@ export const treeNodePropsPass = {
type: Boolean,
default: true,
},
+ showLineNumber: {
+ type: Boolean,
+ default: false,
+ },
// Whether to trigger selection when clicking on the node.
selectOnClickNode: {
type: Boolean,
@@ -227,9 +231,11 @@ export default defineComponent({
showLength,
collapsed,
showLine,
+ showLineNumber,
editable,
editableTrigger,
showIcon,
+ style,
} = this;
const {
@@ -246,10 +252,14 @@ export default defineComponent({
class={{
'vjs-tree__node': true,
'has-selector': showSelectController,
+ 'has-carets': showIcon,
'is-highlight': highlightSelectedNode && checked,
}}
onClick={onNodeClick}
+ style={style}
>
+ {showLineNumber && {node.id + 1}}
+
{showSelectController &&
state.selectable &&
node.type !== 'objectEnd' &&
diff --git a/src/components/TreeNode/styles.less b/src/components/TreeNode/styles.less
index 95c9629..3d7147d 100644
--- a/src/components/TreeNode/styles.less
+++ b/src/components/TreeNode/styles.less
@@ -9,8 +9,13 @@
position: relative;
line-height: 20px;
- &.has-selector {
- padding-left: @selector-span;
+ &.has-carets {
+ padding-left: 15px;
+ }
+
+ &.has-selector,
+ &.has-carets.has-selector {
+ padding-left: 30px;
}
&.is-highlight,
@@ -32,6 +37,12 @@
}
}
+.@{css-prefix}-node__index {
+ position: absolute;
+ right: 100%;
+ margin-right: 4px;
+}
+
.@{css-prefix}-comment {
color: @comment-color;
}
diff --git a/src/themes.less b/src/themes.less
index 1ed2bfa..e187a67 100644
--- a/src/themes.less
+++ b/src/themes.less
@@ -21,6 +21,3 @@
/* common border-color */
@border-color: #bfcbd9;
-
-/* 左侧可选区域占用空间 */
-@selector-span: 30px;