I feel you, it’s a bit overwhelming at first. I’ll try to be short 
First of all, you need to implement the UmbPropertyEditorUiElement like this:
import { LitElement, ... } from "@umbraco-cms/backoffice/external/lit";
import { UmbPropertyEditorUiElement, ... } from "@umbraco-cms/backoffice/property-editor";
export default class ExamplePropertyEditorUIElement extends UmbElementMixin(LitElement) implements UmbPropertyEditorUiElement
{
}
This interface makes you implement the value property. The value is what is saved to Umbraco and loaded from Umbraco. So if you set something in the property and the user presses save or save and publish in the backoffice, anything in value will be stored. You don’t need to do any custom logic for saving, except setting the value property.
Value will be populated with the saved value once your component loads, so no custom loading code either.
import { LitElement, ... } from "@umbraco-cms/backoffice/external/lit";
import { UmbPropertyEditorUiElement, ... } from "@umbraco-cms/backoffice/property-editor";
export default class ExamplePropertyEditorUIElement extends UmbElementMixin(LitElement) implements UmbPropertyEditorUiElement
{
/**
* Defines the actual data of the editor that will be saved to Umbraco and get populated automatically when the editor is loaded
* Make sure to call the #dispatchPropertyValueChanged() function when the value changes to notify Umbraco of the change
*/
@property({ type: String })
public value: undefined | ExampleModel;
}
Ok I lied a little for simplicity’s sake. As you can see, the only other thing you need to do, except setting the correct value in to the value property, is dispatching events to let Umbraco know the value changed. If you don’t do this, the changes will not be saved.
import { LitElement, ... } from "@umbraco-cms/backoffice/external/lit";
import { UmbPropertyEditorUiElement, ... } from "@umbraco-cms/backoffice/property-editor";
export default class ExamplePropertyEditorUIElement extends UmbElementMixin(LitElement) implements UmbPropertyEditorUiElement
{
/**
* Defines the actual data of the editor that will be saved to Umbraco and get populated automatically when the editor is loaded
* Make sure to call the #dispatchPropertyValueChanged() function when the value changes to notify Umbraco of the change
*/
@property({ type: String })
public value: undefined | ExampleModel;
/**
* Updates the value of the editor and dispatches a property value change event.
* @param newValue The new value to set the editor to
*/
#updatePropertyEditorValue(newValue: undefined | ExampleModel) {
this.value = newValue;
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
}
I usually just make a function called UpdatePropertyEditorValue (see above) so it’s sets the new value AND dispatches the event.
This is the very basics of the property editor and how it works.
If your property editor has settings, you can implement the config property.
/** Gets the editor configuration and sets the appropriate variables based on it */
@property({ attribute: false })
public set config(config: UmbPropertyEditorConfigCollection) {
this.allowCustomAspectRatio = config.getValueByAlias("customAspectRatioEnabled") ?? false;
}