UNPKG

@form-create/vant

Version:

VantUI版本低代码表单|FormCreate 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的低代码表单生成组件。支持6个UI框架,适配移动端,并且支持生成任何 Vue 组件。内置20种常用表单组件和自定义组件,再复杂的表单都可以轻松搞定。

114 lines (103 loc) 3.89 kB
import {defineComponent, ref, toRef, watch} from 'vue'; const NAME = 'fcCascader'; export default defineComponent({ name: NAME, inheritAttrs: false, props: { placeholder: String, disabled: Boolean, clearable: Boolean, fieldNames: Object, modelValue: [String, Number], options: Array, minDate: [String, Date], maxDate: [String, Date], }, emits: ['update:modelValue', 'fc.el', 'change'], setup(props, _) { const show = ref(false); const modelValue = toRef(props, 'modelValue'); const options = toRef(props, 'options'); const fieldNames = toRef(props, 'fieldNames', {}); const findOptions = (options, value, path) => { for (let i = 0; i < options.length; i++) { if (options[i][fieldNames.value.value || 'value'] === value) { return [...path, options[i]]; } else if (options[i][fieldNames.value.children || 'children']) { const find = findOptions(options[i][fieldNames.value.children || 'children'], value, [...path, options[i]]); if (find) { return find; } } } } const updateInputValue = (n) => { if (n == null || n === '') { return ''; } const path = findOptions(options.value, n, []); return path ? path.map((option) => option[fieldNames.value.text || 'text']).join(' / ') : n; } const inputValue = ref(updateInputValue(modelValue.value)); watch(() => modelValue.value, (n) => { inputValue.value = updateInputValue(n); }); watch(() => options.value, () => { if (modelValue.value != null && modelValue.value !== '') { inputValue.value = updateInputValue(modelValue.value); } }, {deep: true}); const onInput = (val) => { _.emit('update:modelValue', val); _.emit('change', val); } return { show, inputValue, options, open() { if (props.disabled) { return; } show.value = true; }, confirm({selectedOptions, value}) { inputValue.value = selectedOptions.map((option) => option[fieldNames.value.text || 'text']).join(' / '); show.value = false; onInput(value); }, clear(e) { e.stopPropagation(); inputValue.value = ''; onInput(''); } } }, render() { const clearIcon = () => { return this.$props.clearable && this.inputValue ? <i class="van-badge__wrapper van-icon van-icon-clear van-field__clear" onClick={this.clear}></i> : undefined; } return <div class="_fc-cascader"> <van-field ref="el" placeholder={this.placeholder} readonly disabled={this.$props.disabled} onClick={this.open} model-value={this.inputValue} border={false} isLink v-slots={{ 'right-icon': clearIcon }}/> <van-popup show={this.show} onUpdate:show={(v) => this.show = v} round position="bottom"> <van-cascader {...this.$attrs} modelValue={this.modelValue} fieldNames={this.fieldNames} options={this.options} onClose={() => this.show = false} onFinish={this.confirm} /> </van-popup> </div> }, mounted() { this.$emit('fc.el', this.$refs.el); } });