@type32/yaml-editor-form 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -0
- package/dist/module.json +1 -1
- package/dist/runtime/components/YamlFormEditor.vue +12 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,6 +100,35 @@ const data = ref({
|
|
|
100
100
|
</template>
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
+
### With Writable Computed
|
|
104
|
+
|
|
105
|
+
The editor fully supports writable computed refs for v-model:
|
|
106
|
+
|
|
107
|
+
```vue
|
|
108
|
+
<script setup lang="ts">
|
|
109
|
+
const rawData = ref({
|
|
110
|
+
title: 'Article',
|
|
111
|
+
published: false
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
// Writable computed with getter/setter
|
|
115
|
+
const data = computed({
|
|
116
|
+
get: () => rawData.value,
|
|
117
|
+
set: (value) => {
|
|
118
|
+
console.log('Data updated:', value)
|
|
119
|
+
rawData.value = value
|
|
120
|
+
// You can add validation, transformations, API calls, etc.
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
<template>
|
|
126
|
+
<YamlFormEditor v-model="data" />
|
|
127
|
+
</template>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Note:** The editor properly triggers computed setters by creating new object references instead of mutating in place, ensuring full compatibility with writable computed refs.
|
|
131
|
+
|
|
103
132
|
### With Custom Field Types
|
|
104
133
|
|
|
105
134
|
```vue
|
|
@@ -1087,12 +1116,42 @@ When using `baseType`, conversion rules follow this logic:
|
|
|
1087
1116
|
]
|
|
1088
1117
|
```
|
|
1089
1118
|
|
|
1119
|
+
### Writable Computed Support
|
|
1120
|
+
|
|
1121
|
+
The editor is fully compatible with writable computed refs. All mutations create new object references instead of mutating in place:
|
|
1122
|
+
|
|
1123
|
+
```typescript
|
|
1124
|
+
// ✅ Creates new object (triggers computed setter)
|
|
1125
|
+
data.value = { ...data.value, newField: 'value' }
|
|
1126
|
+
|
|
1127
|
+
// ❌ Direct mutation (doesn't trigger computed setter)
|
|
1128
|
+
data.value.newField = 'value' // Old approach - now fixed!
|
|
1129
|
+
```
|
|
1130
|
+
|
|
1131
|
+
**Use Cases for Writable Computed:**
|
|
1132
|
+
- Validation before saving
|
|
1133
|
+
- Transform data on save (e.g., serialize dates)
|
|
1134
|
+
- Sync with external state management (Pinia, Vuex)
|
|
1135
|
+
- Trigger side effects on changes (API calls, logging)
|
|
1136
|
+
- Implement undo/redo functionality
|
|
1137
|
+
|
|
1138
|
+
**Example with Pinia:**
|
|
1139
|
+
```typescript
|
|
1140
|
+
const store = useMyStore()
|
|
1141
|
+
|
|
1142
|
+
const data = computed({
|
|
1143
|
+
get: () => store.formData,
|
|
1144
|
+
set: (value) => store.updateFormData(value)
|
|
1145
|
+
})
|
|
1146
|
+
```
|
|
1147
|
+
|
|
1090
1148
|
### Performance Considerations
|
|
1091
1149
|
|
|
1092
1150
|
**Reactivity:**
|
|
1093
1151
|
- Uses Vue 3 `ref` and `computed` for optimal reactivity
|
|
1094
1152
|
- Deep watching is used only where necessary
|
|
1095
1153
|
- Recursive rendering is optimized with `v-if` conditionals
|
|
1154
|
+
- **Immutable updates** ensure computed setters are triggered properly
|
|
1096
1155
|
|
|
1097
1156
|
**Large Arrays:**
|
|
1098
1157
|
- Each array item is independently reactive
|
|
@@ -1103,6 +1162,7 @@ When using `baseType`, conversion rules follow this logic:
|
|
|
1103
1162
|
- Date helper functions are minimal
|
|
1104
1163
|
- No global state except type registry
|
|
1105
1164
|
- Components clean up properly on unmount
|
|
1165
|
+
- Immutable updates create minimal object copies (spread operator is fast)
|
|
1106
1166
|
|
|
1107
1167
|
### Validation (Future)
|
|
1108
1168
|
|
package/dist/module.json
CHANGED
|
@@ -16,11 +16,15 @@ watch(data, () => {
|
|
|
16
16
|
function addField(fieldType = "string") {
|
|
17
17
|
if (!data.value) data.value = {};
|
|
18
18
|
const newKey = `field_${Object.keys(data.value).length + 1}`;
|
|
19
|
-
data.value
|
|
19
|
+
data.value = {
|
|
20
|
+
...data.value,
|
|
21
|
+
[newKey]: getDefaultValue(fieldType)
|
|
22
|
+
};
|
|
20
23
|
}
|
|
21
24
|
function removeField(key) {
|
|
22
25
|
if (data.value) {
|
|
23
|
-
|
|
26
|
+
const { [key]: removed, ...rest } = data.value;
|
|
27
|
+
data.value = rest;
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
30
|
const addFieldOptions = computed(() => {
|
|
@@ -42,9 +46,12 @@ const addFieldOptions = computed(() => {
|
|
|
42
46
|
:size="size"
|
|
43
47
|
@remove="removeField(String(key))"
|
|
44
48
|
@update:field-key="(newKey) => {
|
|
45
|
-
if (newKey !== key) {
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
if (newKey !== key && data) {
|
|
50
|
+
const { [key]: value, ...rest } = data;
|
|
51
|
+
data = {
|
|
52
|
+
...rest,
|
|
53
|
+
[newKey]: value
|
|
54
|
+
};
|
|
48
55
|
}
|
|
49
56
|
}"
|
|
50
57
|
>
|