UNPKG

@muban/muban

Version:

Writing components for server-rendered HTML

67 lines (66 loc) 2.9 kB
import { enableTracking, pauseTracking } from '@vue/reactivity'; import { unref, watchEffect } from '@vue/runtime-core'; import { checkInitialBindingState } from '../utils/checkInitialBindingState'; function isInputElement(element) { var _a; return ((_a = element.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'input'; } export function valueBinding(target, model, bindingHelpers) { var _a; const tagName = (_a = target.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase(); if (isInputElement(target) && (target.type === 'checkbox' || target.type === 'radio')) { bindingHelpers.setBinding('checkedValue', model); return; } // TODO: allow users specify events to watch besides the default "change" we are using const updateModel = () => { const newValue = target.value; if (tagName === 'select') { // TODO: options metadata? model.value = newValue; } else { model.value = newValue; } }; const updateHtml = () => { let modelValue = unref(model); if (tagName === 'select') { const element = target; // A blank string or null value will select the caption if (modelValue === '' || modelValue === null) { modelValue = undefined; } const allowUnset = unref(bindingHelpers.getBinding('allowUnset')); // find selected option // TODO: options metadata? const selection = Array.from(element.options).findIndex((option) => option.value === modelValue || (modelValue === undefined && option.value === '')); // set the new value if allowed if (allowUnset || selection >= 0 || (modelValue === undefined && element.size > 1)) { element.selectedIndex = selection; } if (!allowUnset && modelValue !== element.value) { // If you try to set a model value that can't be represented in an already-populated dropdown, reject that change, // because you're not allowed to have a model value that disagrees with a visible UI selection. pauseTracking(); model.value = element.value; enableTracking(); } } else { if (modelValue === null || modelValue === undefined) { modelValue = ''; } target.value = String(modelValue); } }; if (checkInitialBindingState('value', target.value, model.value, unref(bindingHelpers.getBinding('initialValueSource'))) === 'binding') { updateModel(); } const unwatch = watchEffect(updateHtml); target.addEventListener('change', updateModel); return () => { unwatch(); target.removeEventListener('change', updateModel); }; }