如何将自定义组件输入值联动到对象并实现函数复用?
问题与解决方案
核心问题
原代码存在三个关键问题导致组件和对象无法关联:
- 使用全局变量
pair传递键值,所有自定义组件会共享最后一次循环的键值,无法独立绑定各自的属性 - 输入框未绑定值变化事件,无法触发同步逻辑
- 自定义组件未与数据源建立直接关联,无法将输入值同步回原对象
修复方案
1. 重构自定义组件
让组件通过自定义属性接收键和初始值,内部管理输入框,并提供值变化的回调机制,确保组件独立可复用。
2. 绑定值同步逻辑
在组件内部给输入框添加input事件监听,实时将输入值同步回目标对象,同时支持触发外部回调扩展逻辑。
3. 优化组件生成函数
生成组件时,将对应对象的键和值通过属性传递给组件,同时为每个组件绑定专属的同步逻辑,确保每个输入框对应对象的正确属性。
修改后的完整代码
main.js
window.onload = () => { // 目标SVG配置对象 const testObj = { id: 'SVG0', x1: '90', y1: '90', x2: '246', y2: '246' }; // 可复用的自定义设置组件 class SettingsTest extends HTMLElement { static get observedAttributes() { return ['prop-key', 'prop-value']; } constructor() { super(); this.onInputChange = this.onInputChange.bind(this); this.valueChangeCallback = null; } connectedCallback() { this.render(); this.inputEl = this.querySelector('.propValues'); this.inputEl.addEventListener('input', this.onInputChange); } disconnectedCallback() { this.inputEl.removeEventListener('input', this.onInputChange); } attributeChangedCallback(name, oldValue, newValue) { if (name === 'prop-value' && this.inputEl && oldValue !== newValue) { this.inputEl.value = newValue; } } render() { const key = this.getAttribute('prop-key'); const value = this.getAttribute('prop-value'); this.innerHTML = ` <div class="input-element" style="margin-bottom: 30px; width: 100px"> <div> <label class="attributes" data-shrink="true">${key}</label> <div class="input-container"> <input aria-invalid="false" type="text" class="propValues" value="${value}"> </div> </div> </div> `; } onInputChange(e) { const newValue = e.target.value; const key = this.getAttribute('prop-key'); // 触发外部回调,同步到目标对象 if (this.valueChangeCallback) { this.valueChangeCallback(key, newValue); } } // 设置值变化的回调函数 setOnValueChange(callback) { this.valueChangeCallback = callback; } } customElements.define('settings-test', SettingsTest); // 可复用的组件生成函数 function appendComponents(obj, tag, parentId) { const parent = document.getElementById(parentId); parent.replaceChildren(); Object.keys(obj).forEach((key, index) => { const newEl = document.createElement(tag); newEl.setAttribute('id', `prop${index}`); newEl.setAttribute('prop-key', key); newEl.setAttribute('prop-value', obj[key]); // 绑定值同步逻辑:更新原对象 newEl.setOnValueChange((propKey, newValue) => { obj[propKey] = newValue; // 可选:打印查看同步效果 console.log('对象已更新:', obj); }); parent.appendChild(newEl); }); } // 初始化生成组件 appendComponents(testObj, 'settings-test', 'container'); }
CSS
input { margin-top: 0px; background: none; font-size: 18px; color:#a5bae3; height: 50px; border: none; border-bottom:1px solid #a5bae3; width: 90%; align-items:baseline; height: 25px; margin-left:5px; } *:focus { outline: none; color: blue; }
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="styles.css"> <title>Test Input FROM CUSTOM</title> <script src="main.js"></script> </head> <body> <div id="container"></div> </body> </html>
关键改进点
- 组件独立性:通过自定义属性传递数据,不再依赖全局变量,组件可在任何场景复用
- 实时同步:输入框
input事件触发时立即同步值到原对象,支持实时更新SVG配置 - 可扩展性:组件提供
setOnValueChange回调,可灵活添加额外逻辑(比如实时更新SVG元素) - 生命周期管理:正确处理组件的连接/断开事件,避免内存泄漏
内容的提问来源于stack exchange,提问作者user16553022
相关产品推荐
相关产品推荐

