song-ui-u
Version:
vue3 + js的PC前端组件库
194 lines (175 loc) • 6.33 kB
JavaScript
'use strict';
var vue = require('vue');
var index$1 = require('../../../hook/use-namespace/index.cjs');
var index = require('../../../hook/use-style/index.cjs');
require('../../../hook/use-zindex/index.cjs');
var constant = require('./constant.cjs');
var useFormItem = require('./composables/use-form-item.cjs');
var AsyncValidator = require('async-validator');
var _pluginVue_exportHelper = require('../../../_virtual/_plugin-vue_export-helper.cjs');
const __default__ = { name: "x-form-item" };
const _sfc_main = /*#__PURE__*/Object.assign(__default__, {
props: {
label: {
type: String,
default: "",
},
labelWidth: {
type: String,
default: "",
},
align: {
type: String,
default: "right",
},
prop: {
type: String,
default: "",
},
rules: {
type: [Object, Array],
default: () => [],
},
required: Boolean,
},
setup(__props, { expose: __expose }) {
__expose();
const ns = index$1.useNamespace("form-item");
const uStyle = index.useStyle();
const { formContent } = useFormItem.useFormItem();
const props = __props;
// 初始值
let initValue = null;
// 校验结果message
const validateMessage = vue.ref("");
const width = vue.computed(() =>
uStyle.width(formContent.labelWidth.value || props.labelWidth)
);
const textAlign = vue.computed(() => formContent.align.value || props.align);
const isRequired = vue.computed(() =>
initRules.value.some((rule) => rule.required)
);
const controlSize = vue.computed(() => formContent.size.value);
const isColon = vue.computed(() => formContent.colon.value);
/** 转换为数组 */
const convertArray = (rules) => {
return rules ? (Array.isArray(rules) ? rules : [rules]) : [];
};
/** 校验规则集合 */
const initRules = vue.computed(() => {
const _rules = convertArray(props.rules);
const formRules = formContent?.rules?.value;
if (formRules && props.prop) {
const propRules = formRules[props.prop];
propRules && _rules.push(...convertArray(propRules));
}
return _rules;
});
/** 根据触发类型过滤规则 */
const filterRules = (trigger) => {
const rules = initRules.value;
return rules.filter((rule) => {
if (!rule.trigger || !trigger) return true;
if (Array.isArray(rule.trigger)) {
return rule.trigger.includes(trigger);
} else {
return rule.trigger === trigger;
}
});
};
const validate = (trigger) => {
const rules = filterRules(trigger);
// 获取key
const propName = props.prop;
// 根据key获取校验规则
const formModel = formContent?.model?.value;
// 实例化
const validator = new AsyncValidator({
[propName]: rules,
});
// 开始校验
return validator
.validate({ [propName]: formModel[propName] }, { firstFields: true })
.then(() => {
onalidateSuccess();
return Promise.resolve();
})
.catch(({ errors, fields }) => {
validateFailed(errors);
return Promise.reject(errors);
});
};
const onalidateSuccess = () => {
validateMessage.value = "";
};
const validateFailed = (errors) => {
validateMessage.value = errors?.[0].message;
};
const resetField = () => {
props.prop && (formContent.model.value[props.prop] = initValue);
};
const context = vue.reactive({
...vue.toRefs(props),
validate,
resetField,
});
vue.provide(constant.FORM_ITEM_KEY, context);
vue.onMounted(() => {
if (props.prop) {
formContent.pushField(context);
initValue = formContent?.model?.value?.[props.prop];
}
});
const __returned__ = { ns, uStyle, formContent, props, get initValue() { return initValue }, set initValue(v) { initValue = v; }, validateMessage, width, textAlign, isRequired, controlSize, isColon, convertArray, initRules, filterRules, validate, onalidateSuccess, validateFailed, resetField, context, ref: vue.ref, reactive: vue.reactive, toRefs: vue.toRefs, computed: vue.computed, provide: vue.provide, onMounted: vue.onMounted, get useNamespace() { return index$1.useNamespace }, get useStyle() { return index.useStyle }, get FORM_ITEM_KEY() { return constant.FORM_ITEM_KEY }, get useFormItem() { return useFormItem.useFormItem }, get AsyncValidator() { return AsyncValidator } };
Object.defineProperty(__returned__, '__isScriptSetup', { enumerable: false, value: true });
return __returned__
}
});
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return (vue.openBlock(), vue.createElementBlock("div", {
class: vue.normalizeClass([
$setup.ns.b(),
$setup.ns.m('size', $setup.controlSize),
$setup.ns.is('required', $setup.isRequired),
$setup.ns.m('label', $setup.textAlign),
])
}, [
($props.label)
? (vue.openBlock(), vue.createElementBlock("div", {
key: 0,
class: vue.normalizeClass([$setup.ns.e('label')]),
style: vue.normalizeStyle([$setup.width])
}, [
vue.createElementVNode("label", {
class: vue.normalizeClass([$setup.ns.e('label-inner'), $setup.ns.is('colon', $setup.isColon)]),
style: vue.normalizeStyle([$setup.textAlign])
}, vue.toDisplayString($props.label), 7 /* TEXT, CLASS, STYLE */)
], 6 /* CLASS, STYLE */))
: vue.createCommentVNode("v-if", true),
vue.createElementVNode("div", {
class: vue.normalizeClass([$setup.ns.e('control')])
}, [
vue.createElementVNode("div", {
class: vue.normalizeClass([$setup.ns.e('control-inner')])
}, [
vue.renderSlot(_ctx.$slots, "default")
], 2 /* CLASS */),
vue.createVNode(vue.Transition, {
name: `${$setup.ns.namespace}-form-message`
}, {
default: vue.withCtx(() => [
($setup.validateMessage)
? (vue.openBlock(), vue.createElementBlock("div", {
key: 0,
class: vue.normalizeClass([$setup.ns.e('message')])
}, vue.toDisplayString($setup.validateMessage), 3 /* TEXT, CLASS */))
: vue.createCommentVNode("v-if", true)
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["name"])
], 2 /* CLASS */)
], 2 /* CLASS */))
}
var FormItem = /*#__PURE__*/_pluginVue_exportHelper(_sfc_main, [['render',_sfc_render],['__file',"E:\\code\\my-code\\song-ui-ultra\\packages\\components\\form\\src\\formItem.vue"]]);
module.exports = FormItem;
//# sourceMappingURL=formItem.vue.cjs.map