Reactive Data
Enable elements to support reactive data in frameworks such as Vue / React.
Both modifying element data and modifying reactive data will stay in sync.
Key Property
proxyData: IUIInputData
Getter for reactive data used to proxy element data.
TIP
Note: Accessing proxyData will automatically create a reactive data object __proxyData. Use it carefully, as it increases memory usage.
// After deselecting an element, it is recommended to clear proxy data immediately
// otherwise it will keep extra memory and cache outdated data
ui.clearProxyData()Data Hierarchy
Currently only first-level properties support reactivity. For object or array values, you must replace them with a new object to trigger updates.
proxyData.fill.rotation = 30 // invalid
proxyData.fill = proxyData.fill // invalid
proxyData.fill = { ...proxyData.fill, rotation: 30 } // valid, new object createdInternal Methods (Framework Integration)
Vue 3 example provided (proxyData.ts). More framework plugins will be added later.
createProxyData ( ): IUIInputData
Create reactive data __proxyData based on different frameworks (internal use).
clearProxyData ( ): IUIInputData
Clear proxy data. After deselecting elements, it is recommended to clear it immediately to avoid memory leaks and stale cache.
setProxyAttr ( name: string, newValue: IValue )
Synchronize proxy data when setting element properties (internal use).
getProxyAttr ( name: string ): IValue
When getting element properties, prioritize returning proxy data (internal use).
Belongs to
UI Element
Example
Reactive data in Vue 3
You can see the value in the UI automatically changes from 100 → 1 → 2, and then becomes 3 after clicking.
<script setup lang="ts">
import { Rect } from 'leafer-ui'
import './proxyData' // override proxyData, only needs to be imported once globally
const rect = new Rect()
const proxyData = rect.proxyData // get reactive proxy data
setTimeout(() => {
proxyData.width = 1 // update reactive proxy data, UI updates automatically
}, 1000)
setTimeout(() => {
rect.width = 2 // update element data, UI updates automatically
}, 2000)
</script>
<template>
<div class="rect" @click="rect.width = 3">{{ proxyData.width }}</div>
</template>
<style scoped>
.rect {
font-size: 200px;
cursor: pointer;
}
</style>import { shallowReactive, watch } from 'vue'
import { UI, defineKey } from 'leafer-ui'
// define proxyData
defineKey(UI.prototype, 'proxyData', {
get() {
return this.__proxyData
? this.__proxyData
: (this.__proxyData = this.createProxyData())
},
})
// sync proxy data when setting element properties
UI.prototype.setProxyAttr = function (name: string, newValue: unknown): void {
const data = this.__proxyData as any
if (data[name] !== newValue) data[name] = newValue
}
// prioritize proxy data when getting element properties
UI.prototype.getProxyAttr = function (name: string): any {
const value = (this.__proxyData as any)[name]
return value === undefined ? this.__.__get(name) : value
}
// create reactive data
UI.prototype.createProxyData = function () {
// 1. get all style data (including defaults)
const data = this.__.__getData()
// 2. create reactive data
const proxyData = shallowReactive(data)
// 3. watch changes and sync back to element
for (const name in data) {
watch(
() => proxyData[name],
(newValue) => {
if (this.__.__get(name) !== newValue) (this as any)[name] = newValue
},
)
}
return proxyData
}
// clear reactive data
UI.prototype.clearProxyData = function () {
if (this.__proxyData) delete this.__proxyData
}