Skip to content

Commit 2c7af4a

Browse files
committed
feat: support editable.
1 parent b7b6da7 commit 2c7af4a

File tree

6 files changed

+209
-78
lines changed

6 files changed

+209
-78
lines changed

example/App.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Basic from './Basic';
22
import VirtualList from './VirtualList';
33
import SelectControl from './SelectControl';
4+
import Editable from './Editable';
45
import './styles.less';
56

67
export default {
@@ -21,11 +22,16 @@ export default {
2122
key: 'select-control',
2223
component: <SelectControl />,
2324
},
25+
{
26+
title: 'Editable',
27+
key: 'editable',
28+
component: <Editable />,
29+
},
2430
];
2531

2632
return (
2733
<div class="example">
28-
{list.map(item => (
34+
{list.map((item) => (
2935
<div class="example-box" id={item.key}>
3036
<h2 class="title">{item.title}</h2>
3137
{item.component}

example/Editable.vue

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,36 @@
22
<div class="example-box">
33
<div class="block">
44
<h3>JSON:</h3>
5-
<textarea v-model="state.val" />
5+
<textarea v-model="val" />
66

77
<h3>Options:</h3>
88
<div class="options">
99
<div>
1010
<label>showLength</label>
11-
<input v-model="state.showLength" type="checkbox" />
11+
<input v-model="showLength" type="checkbox" />
1212
</div>
1313
<div>
1414
<label>showLine</label>
15-
<input v-model="state.showLine" type="checkbox" />
15+
<input v-model="showLine" type="checkbox" />
1616
</div>
1717
<div>
1818
<label>showLineNumber</label>
19-
<input v-model="state.showLineNumber" type="checkbox" />
19+
<input v-model="showLineNumber" type="checkbox" />
2020
</div>
2121
<div>
2222
<label>editable</label>
23-
<input v-model="state.editable" type="checkbox" />
23+
<input v-model="editable" type="checkbox" />
2424
</div>
2525
<div>
2626
<label>editableTrigger</label>
27-
<select v-model="state.editableTrigger">
27+
<select v-model="editableTrigger">
2828
<option value="click">click</option>
2929
<option value="dblclick">dblclick</option>
3030
</select>
3131
</div>
3232
<div>
3333
<label>deep</label>
34-
<select v-model="state.deep">
34+
<select v-model="deep">
3535
<option :value="2">2</option>
3636
<option :value="3">3</option>
3737
<option :value="4">4</option>
@@ -42,21 +42,20 @@
4242
<div class="block">
4343
<h3>vue-json-pretty:</h3>
4444
<vue-json-pretty
45-
v-model:data="state.data"
46-
:deep="state.deep"
45+
v-model="data"
46+
:deep="deep"
4747
:show-double-quotes="true"
48-
:show-length="state.showLength"
49-
:show-line="state.showLine"
50-
:show-line-number="state.showLineNumber"
51-
:editable="state.editable"
52-
:editable-trigger="state.editableTrigger"
48+
:show-length="showLength"
49+
:show-line="showLine"
50+
:show-line-number="showLineNumber"
51+
:editable="editable"
52+
:editable-trigger="editableTrigger"
5353
/>
5454
</div>
5555
</div>
5656
</template>
5757

5858
<script>
59-
import { defineComponent, reactive, watch } from 'vue';
6059
import VueJsonPretty from 'src';
6160
6261
const defaultData = {
@@ -85,13 +84,13 @@ const defaultData = {
8584
],
8685
};
8786
88-
export default defineComponent({
87+
export default {
8988
name: 'Editable',
9089
components: {
9190
VueJsonPretty,
9291
},
93-
setup() {
94-
const state = reactive({
92+
data() {
93+
return {
9594
val: JSON.stringify(defaultData),
9695
data: defaultData,
9796
showLength: false,
@@ -100,33 +99,23 @@ export default defineComponent({
10099
editable: true,
101100
editableTrigger: 'click',
102101
deep: 3,
103-
});
104-
105-
watch(
106-
() => state.val,
107-
newVal => {
108-
try {
109-
state.data = JSON.parse(newVal);
110-
} catch (err) {
111-
// console.log('JSON ERROR');
112-
}
113-
},
114-
);
115-
116-
watch(
117-
() => state.data,
118-
newVal => {
119-
try {
120-
state.val = JSON.stringify(newVal);
121-
} catch (err) {
122-
// console.log('JSON ERROR');
123-
}
124-
},
125-
);
126-
127-
return {
128-
state,
129102
};
130103
},
131-
});
104+
watch: {
105+
val(newVal) {
106+
try {
107+
this.data = JSON.parse(newVal);
108+
} catch (err) {
109+
console.log('JSON ERROR');
110+
}
111+
},
112+
data(newVal) {
113+
try {
114+
this.val = JSON.stringify(newVal);
115+
} catch (err) {
116+
console.log('JSON ERROR');
117+
}
118+
},
119+
},
120+
};
132121
</script>

example/SelectControl.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@
6666
</select>
6767
</div>
6868
</div>
69-
<h3>v-model:</h3>
70-
<div>{{ value }}</div>
69+
<h3>selectedValue.sync:</h3>
70+
<div>{{ selectedValue }}</div>
7171
<h3>Current Click:</h3>
7272
<div>path: {{ itemPath }}</div>
7373
<div>
@@ -79,7 +79,7 @@
7979
<h3>vue-json-pretty:</h3>
8080
<vue-json-pretty
8181
v-if="renderOK"
82-
v-model="value"
82+
:selected-value.sync="selectedValue"
8383
:data="data"
8484
:path="path"
8585
:deep="deep"
@@ -141,7 +141,7 @@ export default {
141141
renderOK: true,
142142
val: JSON.stringify(defaultData),
143143
data: defaultData,
144-
value: 'res.error',
144+
selectedValue: 'res.error',
145145
selectableType: 'single',
146146
showSelectController: true,
147147
showLength: false,
@@ -170,9 +170,9 @@ export default {
170170
selectableType(newVal) {
171171
this.renderOK = false;
172172
if (newVal === 'single') {
173-
this.value = 'res.error';
173+
this.selectedValue = 'res.error';
174174
} else if (newVal === 'multiple') {
175-
this.value = ['res.error', 'res.data[0].title'];
175+
this.selectedValue = ['res.error', 'res.data[0].title'];
176176
}
177177
// Re-render because v-model:selectedValue format is different in case 2
178178
this.$nextTick(() => {

src/components/Tree/index.vue

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@
3737
:path-selectable="pathSelectable"
3838
:highlight-selected-node="highlightSelectedNode"
3939
:show-icon="showIcon"
40+
:editable="editable"
41+
:editable-trigger="editableTrigger"
4042
@tree-node-click="onTreeNodeClick"
4143
@brackets-click="onBracketsClick"
4244
@selected-change="onSelectedChange"
45+
@value-change="onValueChange"
4346
:style="itemHeight && itemHeight !== 20 ? { lineHeight: `${itemHeight}px` } : {}"
4447
/>
4548
</div>
@@ -50,14 +53,17 @@
5053

5154
<script>
5255
import TreeNode from 'src/components/TreeNode';
53-
import { jsonFlatten } from 'src/utils';
56+
import { jsonFlatten, cloneDeep } from 'src/utils';
5457
import './styles.less';
5558
5659
export default {
5760
name: 'VueJsonPretty',
5861
components: {
5962
TreeNode,
6063
},
64+
model: {
65+
prop: 'data',
66+
},
6167
props: {
6268
// JSON
6369
data: {
@@ -125,7 +131,7 @@ export default {
125131
},
126132
// When there is a selection function, define the selected path.
127133
// For multiple selections, it is an array ['root.a','root.b'], for single selection, it is a string of 'root.a'.
128-
value: {
134+
selectedValue: {
129135
type: [Array, String],
130136
default: () => '',
131137
},
@@ -153,6 +159,14 @@ export default {
153159
type: Boolean,
154160
default: false,
155161
},
162+
editable: {
163+
type: Boolean,
164+
default: false,
165+
},
166+
editableTrigger: {
167+
type: String,
168+
default: 'click',
169+
},
156170
},
157171
data() {
158172
return {
@@ -213,13 +227,14 @@ export default {
213227
214228
selectedPaths: {
215229
get() {
216-
if (this.value && this.selectableType === 'single') {
217-
return [this.value];
230+
const value = this.selectedValue;
231+
if (value && this.selectableType === 'multiple' && Array.isArray(value)) {
232+
return value;
218233
}
219-
return this.value || [];
234+
return [value];
220235
},
221236
set(val) {
222-
this.$emit('input', val);
237+
this.$emit('update:selectedValue', val);
223238
},
224239
},
225240
@@ -312,6 +327,13 @@ export default {
312327
this.hiddenPaths = newPaths;
313328
}
314329
},
330+
331+
onValueChange(value, path) {
332+
const newData = cloneDeep(this.data);
333+
const rootPath = this.path;
334+
new Function('data', 'val', `data${path.slice(rootPath.length)}=val`)(newData, value);
335+
this.$emit('input', newData);
336+
},
315337
},
316338
};
317339
</script>

0 commit comments

Comments
 (0)