123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- <template>
- <view class="u-form">
- <slot />
- </view>
- </template>
- <script>
- import { props } from "./props.js";
- import { mpMixin } from '../../libs/mixin/mpMixin';
- import { mixin } from '../../libs/mixin/mixin';
- import Schema from "../../libs/util/async-validator";
- import { toast, getProperty, setProperty, deepClone, error } from '../../libs/function/index';
- import test from '../../libs/function/test';
-
- Schema.warning = function() {};
-
- export default {
- name: "u-form",
- mixins: [mpMixin, mixin, props],
- provide() {
- return {
- uForm: this,
- };
- },
- data() {
- return {
- formRules: {},
-
- validator: {},
-
- originalModel: null,
- };
- },
- watch: {
-
- rules: {
- immediate: true,
- handler(n) {
- this.setRules(n);
- },
- },
-
- propsChange(n) {
- if (this.children?.length) {
- this.children.map((child) => {
-
- typeof child.updateParentData == "function" &&
- child.updateParentData();
- });
- }
- },
-
- model: {
- immediate: true,
- handler(n) {
- if (!this.originalModel) {
- this.originalModel = deepClone(n);
- }
- },
- },
- },
- computed: {
- propsChange() {
- return [
- this.errorType,
- this.borderBottom,
- this.labelPosition,
- this.labelWidth,
- this.labelAlign,
- this.labelStyle,
- ];
- },
- },
- created() {
-
-
- this.children = [];
- },
- methods: {
-
- setRules(rules) {
-
- if (Object.keys(rules).length === 0) return;
- if (process.env.NODE_ENV === 'development' && Object.keys(this.model).length === 0) {
- error('设置rules,model必须设置!如果已经设置,请刷新页面。');
- return;
- };
- this.formRules = rules;
-
- this.validator = new Schema(rules);
- },
-
- resetFields() {
- this.resetModel();
- },
-
- resetModel(obj) {
-
- this.children.map((child) => {
- const prop = child?.prop;
- const value = getProperty(this.originalModel, prop);
- setProperty(this.model, prop, value);
- });
- },
-
- clearValidate(props) {
- props = [].concat(props);
- this.children.map((child) => {
-
- if (props[0] === undefined || props.includes(child.prop)) {
- child.message = null;
- }
- });
- },
-
- async validateField(value, callback, event = null) {
-
- this.$nextTick(() => {
-
- const errorsRes = [];
-
- value = [].concat(value);
-
- let promises = this.children.map(child => {
- return new Promise((resolve, reject) => {
-
- const childErrors = [];
- if (value.includes(child.prop)) {
-
- const propertyVal = getProperty(
- this.model,
- child.prop
- );
-
- const propertyChain = child.prop.split(".");
- const propertyName =
- propertyChain[propertyChain.length - 1];
- let rule = []
- if (child.itemRules && child.itemRules.length > 0) {
- rule = child.itemRules
- } else {
- rule = this.formRules[child.prop];
- }
-
- if (!rule) {
- resolve()
- return;
- }
-
- const rules = [].concat(rule);
-
- if (!rules.length) {
- resolve()
- }
- for (let i = 0; i < rules.length; i++) {
- const ruleItem = rules[i];
-
- const trigger = [].concat(ruleItem?.trigger);
-
- if (event && !trigger.includes(event)) {
- resolve()
- continue;
- }
-
- const validator = new Schema({
- [propertyName]: ruleItem,
- });
- validator.validate({
- [propertyName]: propertyVal,
- },
- (errors, fields) => {
- if (test.array(errors)) {
- errors.forEach(element => {
- element.prop = child.prop;
- });
- errorsRes.push(...errors);
- childErrors.push(...errors);
- }
- child.message =
- childErrors[0]?.message ? childErrors[0].message : null;
- if (i == (rules.length - 1)) {
- resolve(errorsRes)
- }
- }
- )
- }
- } else {
- resolve({})
- }
- });
- });
-
- Promise.all(promises)
- .then(results => {
-
- typeof callback === "function" && callback(errorsRes);
- })
- .catch(error => {
- console.error('An error occurred:', error);
- });
- });
- },
-
- validate(callback) {
-
- if (process.env.NODE_ENV === 'development' && Object.keys(this.formRules).length === 0) {
- error('未设置rules,请看文档说明!如果已经设置,请刷新页面。');
- return;
- }
- return new Promise((resolve, reject) => {
-
- this.$nextTick(() => {
-
- const formItemProps = this.children.map(
- (item) => item.prop
- );
-
- this.validateField(formItemProps, (errors) => {
- if(errors.length) {
-
- this.errorType === 'toast' && toast(errors[0].message)
- reject(errors)
- } else {
- resolve(true)
- }
- });
- });
- });
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- </style>
|