-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New base input composable to abstract common editor functionality
This commit brings an important change to the application in terms of abstracting common editor functionality into a composable. While some editors consist of a single base component, such a text field or a select, it could be quite common that an editor component might have a set of interdependent components with (possibly complex) interdependent logic. Ideally, these complexities should be contained within the editor component itself, and should not be exposed to the parent or rest of the application. Similarly, the effort for a developer to create their own custom editor component should ideally be kept low and they shouldn't have to use all of the app-specific inner logic. Therefore, it made sense to: - create a simplified top-down API for new custom editors - provide 'base class' functionality that new custom editors can import The simplified API basically means that custom editors do not have to receive, understand, or manipulate the form data structure anymore in order to achieve two-way binding of their specific data values. The parent component now 'v-model's the correct value within the formData object, and the custom component is (for all intents and purposes) blind to it. The base class functionality is divided into a few steps: - custom editors can wrap their subcomponents into a top-level v-input - the v-input - the v-input is the interface for 2-way binding of the model value from the parent, and between the v-input and its subcomponents, by 'v-model' ing the 'internalValue' - the 'useBaseInput' composable should be imported and used by a custom component. This provides the internalValue and the computed property getter and setter methods for updating 'internalValue'. For this reason the custom editor should provide two main functions as arguments to the composable: - a function to parse the 'v-model'ed values of the subcomponents from 'internalValue', and - a function to determine 'internalValue' from the values of the subcomponents The composable also provides an object 'subValues' to which arbitrary keys can be added with which to 'v-model' the subcomponent values. - The custom component should call defineEmits and pass the result to the composable, in order to establish a function that updates the parent on a local 'internalValue' change. As a demonstration of how this can be implemented, the DateTimePickerEditor and URIeditor components were updated according to this new framework.
- Loading branch information
Showing
5 changed files
with
176 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,57 @@ | ||
// base.js | ||
import { reactive, ref, onMounted, onUnmounted } from 'vue' | ||
import { v4 as uuidv4 } from 'uuid'; | ||
// composables/base.js | ||
import { ref, watch, computed } from 'vue'; | ||
|
||
// by convention, composable function names start with "use" | ||
export function useBaseComponent() { | ||
/** | ||
* Composable for managing the state and behavior of the BaseEditor component. | ||
* | ||
* @param {Object} props - The props passed to the custom input component. | ||
* @param {Function} emit - The emit function to trigger events. | ||
* @param {Function} valueParser - A function to parse the modelValue into subcomponent values. | ||
* @param {Function} valueCombiner - A function to combine subcomponent values into the modelValue. | ||
* @returns {Object} - Returns an object containing reactive references and methods for managing the input state. | ||
*/ | ||
|
||
var my_uid = ref(null) | ||
export function useBaseInput(props, emit, valueParser, valueCombiner) { | ||
/** | ||
* Reactive object to hold the individual values of subcomponents. | ||
* @type {Object} | ||
*/ | ||
const subValues = ref(valueParser(props.modelValue) || {}); | ||
|
||
function assignUUID() { | ||
my_uid = uuidv4(); | ||
} | ||
/** | ||
* Computed property to manage the internal value of the custom input component. | ||
* - The getter combines the subcomponent values into the modelValue. | ||
* - The setter parses the modelValue back into subcomponent values. | ||
*/ | ||
const internalValue = computed({ | ||
get() { | ||
return valueCombiner(subValues.value); | ||
}, | ||
set(value) { | ||
subValues.value = valueParser(value); | ||
} | ||
}); | ||
|
||
/** | ||
* Watcher for the parent component's modelValue. | ||
* Updates internal values when modelValue changes. | ||
*/ | ||
watch( | ||
() => props.modelValue, | ||
(newValue) => { | ||
if (newValue !== internalValue.value) { | ||
internalValue.value = newValue; | ||
} | ||
} | ||
); | ||
|
||
onMounted(() => { | ||
console.log("Component mounted, assigning UUID from composable code:\n") | ||
assignUUID() | ||
console.log(my_uid) | ||
// Emit updates to parent | ||
watch(internalValue, (newValue) => { | ||
emit('update:modelValue', newValue); | ||
}); | ||
|
||
return { | ||
my_uid | ||
} | ||
subValues, | ||
internalValue, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters