Alpine.js中x-model绑定x-data时输入框未重置值的问题
Alpine.js x-model 输入值未被setter接受时输入框未重置问题
问题场景
HTML代码
<input x-data="myInput" type="number" x-model="dataInput">
JavaScript代码
document.addEventListener("alpine:init", () => { Alpine.data('myInput', () => ({ '_dataInput': 50, get dataInput() { return this._dataInput }, set dataInput(val) { if (val < 100) { this._dataInput = val; console.log("new value is:" + this._dataInput); } else { console.log('input out of range'); console.log('current value is:' + this._dataInput); } } })) });
当前现象
输入≥100的数值时,setter会拒绝更新模型值,但输入框仍保留非法输入值,不会自动回退到模型当前的实际值(初始值50或之前的合法值)。
预期行为
输入值不被setter接受时,输入框应自动重置为模型的实际值,与x-model绑定$store时的表现一致。
推测原因
绑定$store时,Alpine会调用el._x_forceModelUpdate函数强制同步输入框值与模型值,但绑定x-data属性时不会触发该方法,导致输入框未被重置:
el._x_forceModelUpdate = (value) => { // 如果嵌套模型键未定义,将默认值设为空字符串 if (value === undefined && typeof expression === 'string' && expression.match(/\./)) value = '' // @todo: 这写法有点糙 window.fromModel = true mutateDom(() => bind(el, 'value', value)) delete window.fromModel }
解决方案
方案一:手动调用_x_forceModelUpdate
在setter拒绝更新时,获取输入框元素并调用该方法同步值:
document.addEventListener("alpine:init", () => { Alpine.data('myInput', () => ({ '_dataInput': 50, get dataInput() { return this._dataInput }, set dataInput(val) { if (val < 100) { this._dataInput = val; console.log("new value is:" + this._dataInput); } else { console.log('input out of range'); console.log('current value is:' + this._dataInput); // 获取输入框并强制同步模型值 const el = document.querySelector('[x-model="dataInput"]'); el._x_forceModelUpdate(this._dataInput); } } })) });
方案二:用$refs直接重置输入框
给输入框加x-ref标记,在setter中直接修改输入框值:
修改后的HTML
<input x-data="myInput" type="number" x-model="dataInput" x-ref="input">
修改后的JavaScript
document.addEventListener("alpine:init", () => { Alpine.data('myInput', () => ({ '_dataInput': 50, get dataInput() { return this._dataInput }, set dataInput(val) { if (val < 100) { this._dataInput = val; console.log("new value is:" + this._dataInput); } else { console.log('input out of range'); console.log('current value is:' + this._dataInput); // 用$refs重置输入框值 this.$refs.input.value = this._dataInput; } } })) });
方案三:结合$nextTick处理DOM更新延迟
如果遇到DOM更新不及时的情况,用$nextTick确保重置操作在DOM更新后执行:
set dataInput(val) { if (val < 100) { this._dataInput = val; console.log("new value is:" + this._dataInput); } else { console.log('input out of range'); console.log('current value is:' + this._dataInput); this.$nextTick(() => { this.$refs.input.value = this._dataInput; }); } }
内容的提问来源于stack exchange,提问作者MilanHorvath
相关产品推荐
相关产品推荐

