风采轮播

This commit is contained in:
qiaocl 2024-01-16 11:01:42 +08:00
parent 8c92bd44a0
commit 0db8fccee1
65 changed files with 2088 additions and 64 deletions

View File

@ -72,7 +72,7 @@
<view class="lan">
<view class="left">产品规格及介绍</view>
<view class="right textarea">
<textarea v-model="content.desc" name="content" :disabled="disabled" maxlength="-1"/>
<textarea v-model="content.desc" name="content" :disabled="disabled" maxlength="-1" />
</view>
</view>
</view>
@ -166,7 +166,7 @@
}
console.log("options", options)
uni.setNavigationBarTitle({
title: this.type == 3 ? "商品信息" : this.active == 8 ? '发布供货' : '我的需求'
title: this.type == 3 ? "发布商品" : this.type == 8 ? '发布供货' : '发布采购'
});
},
methods: {
@ -253,9 +253,10 @@
}
});
},
handlecolse(){
handlecolse() {
this.content.province = ""
this.content.city = ""
this.content.area = ""
},
EditInfo(data) {
let that = this
@ -311,8 +312,8 @@
handleGetRegion(ite) {
console.log("省市区", ite)
this.content.province = ite[0].name
this.content.city = ite[1].name == '全部' ? '' : ite[1].name
// this.content.area = ite[2].name
this.content.city = ite[1].name
this.content.area = ite[2].name
},
//
changeIndustry(e) {

View File

@ -58,7 +58,7 @@
"enablePullDownRefresh": false
}
}, {
},{
"path": "login/editPassword",
"style": {
"navigationBarTitleText": "修改密码",

View File

@ -58,11 +58,18 @@
<text class="ml-10">领导风采</text>
<text class="mr-10">查看更多></text>
</view>
<view class="item mt-15" v-for="(item,index) in list.length>5?list.slice(0,5):list" :key="index" @click="handleDetail(item)" >
<image :src="item.avatar" mode="aspectFill"></image>
<view class="name">{{item.name}}</view>
<view class="post">{{item.posname}}</view>
</view>
<swiper class="swiper " display-multiple-items='5' autoplay="true" circular="true" interval='3000'>
<swiper-item v-for="(item,index) in list" :key="index" @click="handleDetail(item)">
<view class="item mt-15">
<image :src="item.avatar" mode="aspectFill"></image>
<view class="name">{{item.name}}</view>
<view class="post">{{item.posname}}</view>
</view>
</swiper-item>
</swiper>
</view>
<!-- 资讯活动 -->
<view class="zixun">
@ -97,7 +104,7 @@
}
},
computed: {
...mapState(["user", "HomeContent", 'InfoList',"navbarlist"]),
...mapState(["user", "HomeContent", 'InfoList', "navbarlist"]),
mobile() {
return this.user.name ? this.user.cominfo.mobile : ''
},
@ -184,9 +191,10 @@
let that = this
that.$model.getVipList({
pageNo: 1,
pageSize: 6,
pageSize: 100,
}).then(res => {
if (res.code == 0) {
console.log("风采", res.data.rows)
this.list = res.data.rows
}
})
@ -331,6 +339,7 @@
}
}
.notice {
width: 100%;
display: flex;
@ -412,8 +421,14 @@
}
.fengcai {
padding-bottom: 5px;
/deep/swiper {
width:100%;
height: 240rpx;
}
.item {
width: 20%;
width: 100%;
image {
width: 50px;

View File

@ -0,0 +1,92 @@
## 1.4.92023-02-10
- 修复 required 参数无法动态绑定
## 1.4.82022-08-23
- 优化 根据 rules 自动添加 required 的问题
## 1.4.72022-08-22
- 修复 item 未设置 require 属性rules 设置 require 后,星号也显示的 bug详见[https://ask.dcloud.net.cn/question/151540](https://ask.dcloud.net.cn/question/151540)
## 1.4.62022-07-13
- 修复 model 需要校验的值没有声明对应字段时导致第一次不触发校验的bug
## 1.4.52022-07-05
- 新增 更多表单示例
- 优化 子表单组件过期提示的问题
- 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式
## 1.4.42022-07-04
- 更新 删除组件日志
## 1.4.32022-07-04
- 修复 由 1.4.0 引发的 label 插槽不生效的bug
## 1.4.22022-07-04
- 修复 子组件找不到 setValue 报错的bug
## 1.4.12022-07-04
- 修复 uni-data-picker 在 uni-forms-item 中报错的bug
- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
## 1.4.02022-06-30
- 【重要】组件逻辑重构,部分用法用旧版本不兼容,请注意兼容问题
- 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力
- 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃
- 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效
- 新增 onFieldChange 方法可以对子表单进行校验可替代binddata方法
- 新增 子表单的 setRules 方法,配合自定义校验函数使用
- 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则
- 优化 动态表单校验方式废弃拼接name的方式
## 1.3.32022-06-22
- 修复 表单校验顺序无序问题
## 1.3.22021-12-09
-
## 1.3.12021-11-19
- 修复 label 插槽不生效的bug
## 1.3.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-forms](https://uniapp.dcloud.io/component/uniui/uni-forms)
## 1.2.72021-08-13
- 修复 没有添加校验规则的字段依然报错的Bug
## 1.2.62021-08-11
- 修复 重置表单错误信息无法清除的问题
## 1.2.52021-08-11
- 优化 组件文档
## 1.2.42021-08-11
- 修复 表单验证只生效一次的问题
## 1.2.32021-07-30
- 优化 vue3下事件警告的问题
## 1.2.22021-07-26
- 修复 vue2 下条件编译导致destroyed生命周期失效的Bug
- 修复 1.2.1 引起的示例在小程序平台报错的Bug
## 1.2.12021-07-22
- 修复 动态校验表单默认值为空的情况下校验失效的Bug
- 修复 不指定name属性时运行报错的Bug
- 优化 label默认宽度从65调整至70使required为true且四字时不换行
- 优化 组件示例,新增动态校验示例代码
- 优化 组件文档,使用方式更清晰
## 1.2.02021-07-13
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.22021-06-25
- 修复 pattern 属性在微信小程序平台无效的问题
## 1.1.12021-06-22
- 修复 validate-trigger属性为submit且err-show-type属性为toast时不能弹出的Bug
## 1.1.02021-06-22
- 修复 只写setRules方法而导致校验不生效的Bug
- 修复 由上个办法引发的错误提示文字错位的Bug
## 1.0.482021-06-21
- 修复 不设置 label 属性 无法设置label插槽的问题
## 1.0.472021-06-21
- 修复 不设置label属性label-width属性不生效的bug
- 修复 setRules 方法与rules属性冲突的问题
## 1.0.462021-06-04
- 修复 动态删减数据导致报错的问题
## 1.0.452021-06-04
- 新增 modelValue 属性 value 即将废弃
## 1.0.442021-06-02
- 新增 uni-forms-item 可以设置单独的 rules
- 新增 validate 事件增加 keepitem 参数,可以选择那些字段不过滤
- 优化 submit 事件重命名为 validate
## 1.0.432021-05-12
- 新增 组件示例地址
## 1.0.422021-04-30
- 修复 自定义检验器失效的问题
## 1.0.412021-03-05
- 更新 校验器
- 修复 表单规则设置类型为 number 的情况下值为0校验失败的Bug
## 1.0.402021-03-04
- 修复 动态显示uni-forms-item的情况下submit 方法获取值错误的Bug
## 1.0.392021-02-05
- 调整为uni_modules目录规范
- 修复 校验器传入 int 等类型 返回String类型的Bug

View File

@ -0,0 +1,627 @@
<template>
<view class="uni-forms-item"
:class="['is-direction-' + localLabelPos ,border?'uni-forms-item--border':'' ,border && isFirstBorder?'is-first-border':'']">
<slot name="label">
<view class="uni-forms-item__label" :class="{'no-label':!label && !required}"
:style="{width:localLabelWidth,justifyContent: localLabelAlign}">
<text v-if="required" class="is-required">*</text>
<text>{{label}}</text>
</view>
</slot>
<!-- #ifndef APP-NVUE -->
<view class="uni-forms-item__content">
<slot></slot>
<view class="uni-forms-item__error" :class="{'msg--active':msg}">
<text>{{msg}}</text>
</view>
</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<view class="uni-forms-item__nuve-content">
<view class="uni-forms-item__content">
<slot></slot>
</view>
<view class="uni-forms-item__error" :class="{'msg--active':msg}">
<text class="error-text">{{msg}}</text>
</view>
</view>
<!-- #endif -->
</view>
</template>
<script>
/**
* uni-fomrs-item 表单子组件
* @description uni-fomrs-item 表单子组件提供了基础布局已经校验能力
* @tutorial https://ext.dcloud.net.cn/plugin?id=2773
* @property {Boolean} required 是否必填左边显示红色"*"
* @property {String } label 输入框左边的文字提示
* @property {Number } labelWidth label的宽度单位px默认65
* @property {String } labelAlign = [left|center|right] label的文字对齐方式默认left
* @value left label 左侧显示
* @value center label 居中
* @value right label 右侧对齐
* @property {String } errorMessage 显示的错误提示内容如果为空字符串或者false则不显示错误信息
* @property {String } name 表单域的属性名在使用校验规则时必填
* @property {String } leftIcon 1.4.0废弃label左边的图标 uni-ui 的图标名称
* @property {String } iconColor 1.4.0废弃左边通过icon配置的图标的颜色默认#606266
* @property {String} validateTrigger = [bind|submit|blur] 1.4.0废弃校验触发器方式 默认 submit
* @value bind 发生变化时触发
* @value submit 提交时触发
* @value blur 失去焦点触发
* @property {String } labelPosition = [top|left] 1.4.0废弃label的文字的位置默认left
* @value top 顶部显示 label
* @value left 左侧显示 label
*/
export default {
name: 'uniFormsItem',
options: {
virtualHost: true
},
provide() {
return {
uniFormItem: this
}
},
inject: {
form: {
from: 'uniForm',
default: null
},
},
props: {
//
rules: {
type: Array,
default () {
return null;
}
},
// 使
name: {
type: [String, Array],
default: ''
},
required: {
type: Boolean,
default: false
},
label: {
type: String,
default: ''
},
// label 80
labelWidth: {
type: [String, Number],
default: ''
},
// label left left/center/right
labelAlign: {
type: String,
default: ''
},
//
errorMessage: {
type: [String, Boolean],
default: ''
},
// 1.4.0 使 form
// validateTrigger: {
// type: String,
// default: ''
// },
// 1.4.0 使 form label
// labelPosition: {
// type: String,
// default: ''
// },
// 1.4.0 使 #label
leftIcon: String,
iconColor: {
type: String,
default: '#606266'
},
},
data() {
return {
errMsg: '',
userRules: null,
localLabelAlign: 'left',
localLabelWidth: '65px',
localLabelPos: 'left',
border: false,
isFirstBorder: false,
};
},
computed: {
//
msg() {
return this.errorMessage || this.errMsg;
}
},
watch: {
//
'form.formRules'(val) {
// TODO vue3 watch
// #ifndef MP-TOUTIAO
this.init()
// #endif
},
'form.labelWidth'(val) {
//
this.localLabelWidth = this._labelWidthUnit(val)
},
'form.labelPosition'(val) {
//
this.localLabelPos = this._labelPosition()
},
'form.labelAlign'(val) {
}
},
created() {
this.init(true)
if (this.name && this.form) {
// TODO vue3 watch
// #ifdef MP-TOUTIAO
this.$watch('form.formRules', () => {
this.init()
})
// #endif
//
this.$watch(
() => {
const val = this.form._getDataValue(this.name, this.form.localData)
return val
},
(value, oldVal) => {
const isEqual = this.form._isEqual(value, oldVal)
//
// TODO oldVal = undefined ,
// fix by mehaotian && oldVal !== undefined formData
if (!isEqual) {
const val = this.itemSetValue(value)
this.onFieldChange(val, false)
}
}, {
immediate: false
}
);
}
},
// #ifndef VUE3
destroyed() {
if (this.__isUnmounted) return
this.unInit()
},
// #endif
// #ifdef VUE3
unmounted() {
this.__isUnmounted = true
this.unInit()
},
// #endif
methods: {
/**
* 外部调用方法
* 设置规则 主要用于小程序自定义检验规则
* @param {Array} rules 规则源数据
*/
setRules(rules = null) {
this.userRules = rules
this.init(false)
},
//
setValue() {
// console.log('setValue 使 uni-forms ');
},
/**
* 外部调用方法
* 校验数据
* @param {any} value 需要校验的数据
* @param {boolean} 是否立即校验
* @return {Array|null} 校验内容
*/
async onFieldChange(value, formtrigger = true) {
const {
formData,
localData,
errShowType,
validateCheck,
validateTrigger,
_isRequiredField,
_realName
} = this.form
const name = _realName(this.name)
if (!value) {
value = this.form.formData[name]
}
// fixd by mehaotian
// this.errMsg = '';
// fix by mehaotian
const ruleLen = this.itemRules.rules && this.itemRules.rules.length
if (!this.validator || !ruleLen || ruleLen === 0) return;
//
// let trigger = this.isTrigger(this.itemRules.validateTrigger, this.validateTrigger, validateTrigger);
const isRequiredField = _isRequiredField(this.itemRules.rules || []);
let result = null;
// bind
if (validateTrigger === 'bind' || formtrigger) {
//
result = await this.validator.validateUpdate({
[name]: value
},
formData
);
// , , undefined
if (!isRequiredField && (value === undefined || value === '')) {
result = null;
}
//
if (result && result.errorMessage) {
if (errShowType === 'undertext') {
//
this.errMsg = !result ? '' : result.errorMessage;
}
if (errShowType === 'toast') {
uni.showToast({
title: result.errorMessage || '校验错误',
icon: 'none'
});
}
if (errShowType === 'modal') {
uni.showModal({
title: '提示',
content: result.errorMessage || '校验错误'
});
}
} else {
this.errMsg = ''
}
// form
validateCheck(result ? result : null)
} else {
this.errMsg = ''
}
return result ? result : null;
},
/**
* 初始组件数据
*/
init(type = false) {
const {
validator,
formRules,
childrens,
formData,
localData,
_realName,
labelWidth,
_getDataValue,
_setDataValue
} = this.form || {}
//
this.localLabelAlign = this._justifyContent()
//
this.localLabelWidth = this._labelWidthUnit(labelWidth)
//
this.localLabelPos = this._labelPosition()
// form
this.form && type && childrens.push(this)
if (!validator || !formRules) return
// item
if (!this.form.isFirstBorder) {
this.form.isFirstBorder = true;
this.isFirstBorder = true;
}
// group item
if (this.group) {
if (!this.group.isFirstBorder) {
this.group.isFirstBorder = true;
this.isFirstBorder = true;
}
}
this.border = this.form.border;
//
const name = _realName(this.name)
const itemRule = this.userRules || this.rules
if (typeof formRules === 'object' && itemRule) {
//
formRules[name] = {
rules: itemRule
}
validator.updateSchema(formRules);
}
//
const itemRules = formRules[name] || {}
this.itemRules = itemRules
//
this.validator = validator
//
this.itemSetValue(_getDataValue(this.name, localData))
},
unInit() {
if (this.form) {
const {
childrens,
formData,
_realName
} = this.form
childrens.forEach((item, index) => {
if (item === this) {
this.form.childrens.splice(index, 1)
delete formData[_realName(item.name)]
}
})
}
},
// item
itemSetValue(value) {
const name = this.form._realName(this.name)
const rules = this.itemRules.rules || []
const val = this.form._getValue(name, value, rules)
this.form._setDataValue(name, this.form.formData, val)
return val
},
/**
* 移除该表单项的校验结果
*/
clearValidate() {
this.errMsg = '';
},
//
_isRequired() {
// TODO
// if (this.form) {
// if (this.form._isRequiredField(this.itemRules.rules || []) && this.required) {
// return true
// }
// return false
// }
return this.required
},
//
_justifyContent() {
if (this.form) {
const {
labelAlign
} = this.form
let labelAli = this.labelAlign ? this.labelAlign : labelAlign;
if (labelAli === 'left') return 'flex-start';
if (labelAli === 'center') return 'center';
if (labelAli === 'right') return 'flex-end';
}
return 'flex-start';
},
// label ,
_labelWidthUnit(labelWidth) {
// if (this.form) {
// const {
// labelWidth
// } = this.form
return this.num2px(this.labelWidth ? this.labelWidth : (labelWidth || (this.label ? 65 : 'auto')))
// }
// return '65px'
},
// label
_labelPosition() {
if (this.form) return this.form.labelPosition || 'left'
return 'left'
},
/**
* 触发时机
* @param {Object} rule 当前规则内时机
* @param {Object} itemRlue 当前组件时机
* @param {Object} parentRule 父组件时机
*/
isTrigger(rule, itemRlue, parentRule) {
// bind submit
if (rule === 'submit' || !rule) {
if (rule === undefined) {
if (itemRlue !== 'bind') {
if (!itemRlue) {
return parentRule === '' ? 'bind' : 'submit';
}
return 'submit';
}
return 'bind';
}
return 'submit';
}
return 'bind';
},
num2px(num) {
if (typeof num === 'number') {
return `${num}px`
}
return num
}
}
};
</script>
<style lang="scss">
.uni-forms-item {
position: relative;
display: flex;
/* #ifdef APP-NVUE */
// nvue 使 margin-bottom error
padding-bottom: 22px;
/* #endif */
/* #ifndef APP-NVUE */
margin-bottom: 22px;
/* #endif */
flex-direction: row;
&__label {
display: flex;
flex-direction: row;
align-items: center;
text-align: left;
font-size: 14px;
color: #606266;
height: 36px;
padding: 0 12px 0 0;
/* #ifndef APP-NVUE */
vertical-align: middle;
flex-shrink: 0;
/* #endif */
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
&.no-label {
padding: 0;
}
}
&__content {
/* #ifndef MP-TOUTIAO */
// display: flex;
// align-items: center;
/* #endif */
position: relative;
font-size: 14px;
flex: 1;
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
flex-direction: row;
/* #ifndef APP || H5 || MP-WEIXIN || APP-NVUE */
// TODO
&>uni-easyinput,
&>uni-data-picker {
width: 100%;
}
/* #endif */
}
& .uni-forms-item__nuve-content {
display: flex;
flex-direction: column;
flex: 1;
}
&__error {
color: #f56c6c;
font-size: 12px;
line-height: 1;
padding-top: 4px;
position: absolute;
/* #ifndef APP-NVUE */
top: 100%;
left: 0;
transition: transform 0.3s;
transform: translateY(-100%);
/* #endif */
/* #ifdef APP-NVUE */
bottom: 5px;
/* #endif */
opacity: 0;
.error-text {
// nvue
color: #f56c6c;
font-size: 12px;
}
&.msg--active {
opacity: 1;
transform: translateY(0%);
}
}
//
&.is-direction-left {
flex-direction: row;
}
&.is-direction-top {
flex-direction: column;
.uni-forms-item__label {
padding: 0 0 8px;
line-height: 1.5715;
text-align: left;
/* #ifndef APP-NVUE */
white-space: initial;
/* #endif */
}
}
.is-required {
// color: $uni-color-error;
color: #dd524d;
font-weight: bold;
}
}
.uni-forms-item--border {
margin-bottom: 0;
padding: 10px 0;
// padding-bottom: 0;
border-top: 1px #eee solid;
/* #ifndef APP-NVUE */
.uni-forms-item__content {
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
.uni-forms-item__error {
position: relative;
top: 5px;
left: 0;
padding-top: 0;
}
}
/* #endif */
/* #ifdef APP-NVUE */
display: flex;
flex-direction: column;
.uni-forms-item__error {
position: relative;
top: 0px;
left: 0;
padding-top: 0;
margin-top: 5px;
}
/* #endif */
}
.is-first-border {
/* #ifndef APP-NVUE */
border: none;
/* #endif */
/* #ifdef APP-NVUE */
border-width: 0;
/* #endif */
}
</style>

View File

@ -0,0 +1,397 @@
<template>
<view class="uni-forms">
<form>
<slot></slot>
</form>
</view>
</template>
<script>
import Validator from './validate.js';
import {
deepCopy,
getValue,
isRequiredField,
setDataValue,
getDataValue,
realName,
isRealName,
rawData,
isEqual
} from './utils.js'
// #ifndef VUE3
//
import Vue from 'vue';
Vue.prototype.binddata = function(name, value, formName) {
if (formName) {
this.$refs[formName].setValue(name, value);
} else {
let formVm;
for (let i in this.$refs) {
const vm = this.$refs[i];
if (vm && vm.$options && vm.$options.name === 'uniForms') {
formVm = vm;
break;
}
}
if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
formVm.setValue(name, value);
}
};
// #endif
/**
* Forms 表单
* @description 由输入框选择器单选框多选框等控件组成用以收集校验提交数据
* @tutorial https://ext.dcloud.net.cn/plugin?id=2773
* @property {Object} rules 表单校验规则
* @property {String} validateTrigger = [bind|submit|blur] 校验触发器方式 默认 submit
* @value bind 发生变化时触发
* @value submit 提交时触发
* @value blur 失去焦点时触发
* @property {String} labelPosition = [top|left] label 位置 默认 left
* @value top 顶部显示 label
* @value left 左侧显示 label
* @property {String} labelWidth label 宽度默认 65px
* @property {String} labelAlign = [left|center|right] label 居中方式 默认 left
* @value left label 左侧显示
* @value center label 居中
* @value right label 右侧对齐
* @property {String} errShowType = [undertext|toast|modal] 校验错误信息提示方式
* @value undertext 错误信息在底部显示
* @value toast 错误信息toast显示
* @value modal 错误信息modal显示
* @event {Function} submit 提交时触发
* @event {Function} validate 校验结果发生变化触发
*/
export default {
name: 'uniForms',
emits: ['validate', 'submit'],
options: {
virtualHost: true
},
props: {
//
value: {
type: Object,
default () {
return null;
}
},
// vue3 value
modelValue: {
type: Object,
default () {
return null;
}
},
// 1.4.0 v-model value modelValue
model: {
type: Object,
default () {
return null;
}
},
//
rules: {
type: Object,
default () {
return {};
}
},
// undertext [undertext|toast|modal]
errShowType: {
type: String,
default: 'undertext'
},
// bind [bind|submit]
validateTrigger: {
type: String,
default: 'submit'
},
// label left top/left
labelPosition: {
type: String,
default: 'left'
},
// label
labelWidth: {
type: [String, Number],
default: ''
},
// label left left/center/right
labelAlign: {
type: String,
default: 'left'
},
border: {
type: Boolean,
default: false
}
},
provide() {
return {
uniForm: this
}
},
data() {
return {
//
formData: {},
formRules: {}
};
},
computed: {
//
localData() {
const localVal = this.model || this.modelValue || this.value
if (localVal) {
return deepCopy(localVal)
}
return {}
}
},
watch: {
// ,使
// localData: {},
//
rules: {
handler: function(val, oldVal) {
this.setRules(val)
},
deep: true,
immediate: true
}
},
created() {
// #ifdef VUE3
let getbinddata = getApp().$vm.$.appContext.config.globalProperties.binddata
if (!getbinddata) {
getApp().$vm.$.appContext.config.globalProperties.binddata = function(name, value, formName) {
if (formName) {
this.$refs[formName].setValue(name, value);
} else {
let formVm;
for (let i in this.$refs) {
const vm = this.$refs[i];
if (vm && vm.$options && vm.$options.name === 'uniForms') {
formVm = vm;
break;
}
}
if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性');
formVm.setValue(name, value);
}
}
}
// #endif
//
this.childrens = []
// TODO uni-data-picker ,
this.inputChildrens = []
this.setRules(this.rules)
},
methods: {
/**
* 外部调用方法
* 设置规则 主要用于小程序自定义检验规则
* @param {Array} rules 规则源数据
*/
setRules(rules) {
// TODO
this.formRules = Object.assign({}, this.formRules, rules)
//
this.validator = new Validator(rules);
},
/**
* 外部调用方法
* 设置数据用于设置表单数据公开给用户使用 不支持在动态表单中使用
* @param {Object} key
* @param {Object} value
*/
setValue(key, value) {
let example = this.childrens.find(child => child.name === key);
if (!example) return null;
this.formData[key] = getValue(key, value, (this.formRules[key] && this.formRules[key].rules) || [])
return example.onFieldChange(this.formData[key]);
},
/**
* 外部调用方法
* 手动提交校验表单
* 对整个表单进行校验的方法参数为一个回调函数
* @param {Array} keepitem 保留不参与校验的字段
* @param {type} callback 方法回调
*/
validate(keepitem, callback) {
return this.checkAll(this.formData, keepitem, callback);
},
/**
* 外部调用方法
* 部分表单校验
* @param {Array|String} props 需要校验的字段
* @param {Function} 回调函数
*/
validateField(props = [], callback) {
props = [].concat(props);
let invalidFields = {};
this.childrens.forEach(item => {
const name = realName(item.name)
if (props.indexOf(name) !== -1) {
invalidFields = Object.assign({}, invalidFields, {
[name]: this.formData[name]
});
}
});
return this.checkAll(invalidFields, [], callback);
},
/**
* 外部调用方法
* 移除表单项的校验结果传入待移除的表单项的 prop 属性或者 prop 组成的数组如不传则移除整个表单的校验结果
* @param {Array|String} props 需要移除校验的字段 不填为所有
*/
clearValidate(props = []) {
props = [].concat(props);
this.childrens.forEach(item => {
if (props.length === 0) {
item.errMsg = '';
} else {
const name = realName(item.name)
if (props.indexOf(name) !== -1) {
item.errMsg = '';
}
}
});
},
/**
* 外部调用方法 即将废弃
* 手动提交校验表单
* 对整个表单进行校验的方法参数为一个回调函数
* @param {Array} keepitem 保留不参与校验的字段
* @param {type} callback 方法回调
*/
submit(keepitem, callback, type) {
for (let i in this.dataValue) {
const itemData = this.childrens.find(v => v.name === i);
if (itemData) {
if (this.formData[i] === undefined) {
this.formData[i] = this._getValue(i, this.dataValue[i]);
}
}
}
if (!type) {
console.warn('submit 方法即将废弃请使用validate方法代替');
}
return this.checkAll(this.formData, keepitem, callback, 'submit');
},
//
async checkAll(invalidFields, keepitem, callback, type) {
//
if (!this.validator) return
let childrens = []
// item
for (let i in invalidFields) {
const item = this.childrens.find(v => realName(v.name) === i)
if (item) {
childrens.push(item)
}
}
// validatefunciont ,
if (!callback && typeof keepitem === 'function') {
callback = keepitem;
}
let promise;
// 使 Promise
if (!callback && typeof callback !== 'function' && Promise) {
promise = new Promise((resolve, reject) => {
callback = function(valid, invalidFields) {
!valid ? resolve(invalidFields) : reject(valid);
};
});
}
let results = [];
//
let tempFormData = JSON.parse(JSON.stringify(invalidFields))
// ,使 for 使 awiat
for (let i in childrens) {
const child = childrens[i]
let name = realName(child.name);
const result = await child.onFieldChange(tempFormData[name]);
if (result) {
results.push(result);
// toast ,modal
if (this.errShowType === 'toast' || this.errShowType === 'modal') break;
}
}
if (Array.isArray(results)) {
if (results.length === 0) results = null;
}
if (Array.isArray(keepitem)) {
keepitem.forEach(v => {
let vName = realName(v);
let value = getDataValue(v, this.localData)
if (value !== undefined) {
tempFormData[vName] = value
}
});
}
// TODO submit
if (type === 'submit') {
this.$emit('submit', {
detail: {
value: tempFormData,
errors: results
}
});
} else {
this.$emit('validate', results);
}
// const resetFormData = rawData(tempFormData, this.localData, this.name)
let resetFormData = {}
resetFormData = rawData(tempFormData, this.name)
callback && typeof callback === 'function' && callback(results, resetFormData);
if (promise && callback) {
return promise;
} else {
return null;
}
},
/**
* 返回validate事件
* @param {Object} result
*/
validateCheck(result) {
this.$emit('validate', result);
},
_getValue: getValue,
_isRequiredField: isRequiredField,
_setDataValue: setDataValue,
_getDataValue: getDataValue,
_realName: realName,
_isRealName: isRealName,
_isEqual: isEqual
}
};
</script>
<style lang="scss">
.uni-forms {}
</style>

View File

@ -0,0 +1,293 @@
/**
* 简单处理对象拷贝
* @param {Obejct} 被拷贝对象
* @@return {Object} 拷贝对象
*/
export const deepCopy = (val) => {
return JSON.parse(JSON.stringify(val))
}
/**
* 过滤数字类型
* @param {String} format 数字类型
* @@return {Boolean} 返回是否为数字类型
*/
export const typeFilter = (format) => {
return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp';
}
/**
* value 转换成指定的类型用于处理初始值原因是初始值需要入库不能为 undefined
* @param {String} key 字段名
* @param {any} value 字段值
* @param {Object} rules 表单校验规则
*/
export const getValue = (key, value, rules) => {
const isRuleNumType = rules.find(val => val.format && typeFilter(val.format));
const isRuleBoolType = rules.find(val => (val.format && val.format === 'boolean') || val.format === 'bool');
// 输入类型为 number
if (!!isRuleNumType) {
if (!value && value !== 0) {
value = null
} else {
value = isNumber(Number(value)) ? Number(value) : value
}
}
// 输入类型为 boolean
if (!!isRuleBoolType) {
value = isBoolean(value) ? value : false
}
return value;
}
/**
* 获取表单数据
* @param {String|Array} name 真实名称需要使用 realName 获取
* @param {Object} data 原始数据
* @param {any} value 需要设置的值
*/
export const setDataValue = (field, formdata, value) => {
formdata[field] = value
return value || ''
}
/**
* 获取表单数据
* @param {String|Array} field 真实名称需要使用 realName 获取
* @param {Object} data 原始数据
*/
export const getDataValue = (field, data) => {
return objGet(data, field)
}
/**
* 获取表单类型
* @param {String|Array} field 真实名称需要使用 realName 获取
*/
export const getDataValueType = (field, data) => {
const value = getDataValue(field, data)
return {
type: type(value),
value
}
}
/**
* 获取表单可用的真实name
* @param {String|Array} name 表单name
* @@return {String} 表单可用的真实name
*/
export const realName = (name, data = {}) => {
const base_name = _basePath(name)
if (typeof base_name === 'object' && Array.isArray(base_name) && base_name.length > 1) {
const realname = base_name.reduce((a, b) => a += `#${b}`, '_formdata_')
return realname
}
return base_name[0] || name
}
/**
* 判断是否表单可用的真实name
* @param {String|Array} name 表单name
* @@return {String} 表单可用的真实name
*/
export const isRealName = (name) => {
const reg = /^_formdata_#*/
return reg.test(name)
}
/**
* 获取表单数据的原始格式
* @@return {Object|Array} object 需要解析的数据
*/
export const rawData = (object = {}, name) => {
let newData = JSON.parse(JSON.stringify(object))
let formData = {}
for(let i in newData){
let path = name2arr(i)
objSet(formData,path,newData[i])
}
return formData
}
/**
* 真实name还原为 array
* @param {*} name
*/
export const name2arr = (name) => {
let field = name.replace('_formdata_#', '')
field = field.split('#').map(v => (isNumber(v) ? Number(v) : v))
return field
}
/**
* 对象中设置值
* @param {Object|Array} object 源数据
* @param {String| Array} path 'a.b.c' ['a',0,'b','c']
* @param {String} value 需要设置的值
*/
export const objSet = (object, path, value) => {
if (typeof object !== 'object') return object;
_basePath(path).reduce((o, k, i, _) => {
if (i === _.length - 1) {
// 若遍历结束直接赋值
o[k] = value
return null
} else if (k in o) {
// 若存在对应路径,则返回找到的对象,进行下一次遍历
return o[k]
} else {
// 若不存在对应路径,则创建对应对象,若下一路径是数字,新对象赋值为空数组,否则赋值为空对象
o[k] = /^[0-9]{1,}$/.test(_[i + 1]) ? [] : {}
return o[k]
}
}, object)
// 返回object
return object;
}
// 处理 path path有三种形式'a[0].b.c'、'a.0.b.c' 和 ['a','0','b','c'],需要统一处理成数组,便于后续使用
function _basePath(path) {
// 若是数组,则直接返回
if (Array.isArray(path)) return path
// 若有 '[',']',则替换成将 '[' 替换成 '.',去掉 ']'
return path.replace(/\[/g, '.').replace(/\]/g, '').split('.')
}
/**
* 从对象中获取值
* @param {Object|Array} object 源数据
* @param {String| Array} path 'a.b.c' ['a',0,'b','c']
* @param {String} defaultVal 如果无法从调用链中获取值的默认值
*/
export const objGet = (object, path, defaultVal = 'undefined') => {
// 先将path处理成统一格式
let newPath = _basePath(path)
// 递归处理,返回最后结果
let val = newPath.reduce((o, k) => {
return (o || {})[k]
}, object);
return !val || val !== undefined ? val : defaultVal
}
/**
* 是否为 number 类型
* @param {any} num 需要判断的值
* @return {Boolean} 是否为 number
*/
export const isNumber = (num) => {
return !isNaN(Number(num))
}
/**
* 是否为 boolean 类型
* @param {any} bool 需要判断的值
* @return {Boolean} 是否为 boolean
*/
export const isBoolean = (bool) => {
return (typeof bool === 'boolean')
}
/**
* 是否有必填字段
* @param {Object} rules 规则
* @return {Boolean} 是否有必填字段
*/
export const isRequiredField = (rules) => {
let isNoField = false;
for (let i = 0; i < rules.length; i++) {
const ruleData = rules[i];
if (ruleData.required) {
isNoField = true;
break;
}
}
return isNoField;
}
/**
* 获取数据类型
* @param {Any} obj 需要获取数据类型的值
*/
export const type = (obj) => {
var class2type = {};
// 生成class2type映射
"Boolean Number String Function Array Date RegExp Object Error".split(" ").map(function(item, index) {
class2type["[object " + item + "]"] = item.toLowerCase();
})
if (obj == null) {
return obj + "";
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[Object.prototype.toString.call(obj)] || "object" :
typeof obj;
}
/**
* 判断两个值是否相等
* @param {any} a
* @param {any} b
* @return {Boolean} 是否相等
*/
export const isEqual = (a, b) => {
//如果a和b本来就全等
if (a === b) {
//判断是否为0和-0
return a !== 0 || 1 / a === 1 / b;
}
//判断是否为null和undefined
if (a == null || b == null) {
return a === b;
}
//接下来判断a和b的数据类型
var classNameA = toString.call(a),
classNameB = toString.call(b);
//如果数据类型不相等则返回false
if (classNameA !== classNameB) {
return false;
}
//如果数据类型相等,再根据不同数据类型分别判断
switch (classNameA) {
case '[object RegExp]':
case '[object String]':
//进行字符串转换比较
return '' + a === '' + b;
case '[object Number]':
//进行数字转换比较,判断是否为NaN
if (+a !== +a) {
return +b !== +b;
}
//判断是否为0或-0
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
case '[object Date]':
case '[object Boolean]':
return +a === +b;
}
//如果是对象类型
if (classNameA == '[object Object]') {
//获取a和b的属性长度
var propsA = Object.getOwnPropertyNames(a),
propsB = Object.getOwnPropertyNames(b);
if (propsA.length != propsB.length) {
return false;
}
for (var i = 0; i < propsA.length; i++) {
var propName = propsA[i];
//如果对应属性对应值不相等则返回false
if (a[propName] !== b[propName]) {
return false;
}
}
return true;
}
//如果是数组类型
if (classNameA == '[object Array]') {
if (a.toString() == b.toString()) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,486 @@
var pattern = {
email: /^\S+?@\S+?\.\S+?$/,
idcard: /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,
url: new RegExp(
"^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$",
'i')
};
const FORMAT_MAPPING = {
"int": 'integer',
"bool": 'boolean',
"double": 'number',
"long": 'number',
"password": 'string'
// "fileurls": 'array'
}
function formatMessage(args, resources = '') {
var defaultMessage = ['label']
defaultMessage.forEach((item) => {
if (args[item] === undefined) {
args[item] = ''
}
})
let str = resources
for (let key in args) {
let reg = new RegExp('{' + key + '}')
str = str.replace(reg, args[key])
}
return str
}
function isEmptyValue(value, type) {
if (value === undefined || value === null) {
return true;
}
if (typeof value === 'string' && !value) {
return true;
}
if (Array.isArray(value) && !value.length) {
return true;
}
if (type === 'object' && !Object.keys(value).length) {
return true;
}
return false;
}
const types = {
integer(value) {
return types.number(value) && parseInt(value, 10) === value;
},
string(value) {
return typeof value === 'string';
},
number(value) {
if (isNaN(value)) {
return false;
}
return typeof value === 'number';
},
"boolean": function(value) {
return typeof value === 'boolean';
},
"float": function(value) {
return types.number(value) && !types.integer(value);
},
array(value) {
return Array.isArray(value);
},
object(value) {
return typeof value === 'object' && !types.array(value);
},
date(value) {
return value instanceof Date;
},
timestamp(value) {
if (!this.integer(value) || Math.abs(value).toString().length > 16) {
return false
}
return true;
},
file(value) {
return typeof value.url === 'string';
},
email(value) {
return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255;
},
url(value) {
return typeof value === 'string' && !!value.match(pattern.url);
},
pattern(reg, value) {
try {
return new RegExp(reg).test(value);
} catch (e) {
return false;
}
},
method(value) {
return typeof value === 'function';
},
idcard(value) {
return typeof value === 'string' && !!value.match(pattern.idcard);
},
'url-https'(value) {
return this.url(value) && value.startsWith('https://');
},
'url-scheme'(value) {
return value.startsWith('://');
},
'url-web'(value) {
return false;
}
}
class RuleValidator {
constructor(message) {
this._message = message
}
async validateRule(fieldKey, fieldValue, value, data, allData) {
var result = null
let rules = fieldValue.rules
let hasRequired = rules.findIndex((item) => {
return item.required
})
if (hasRequired < 0) {
if (value === null || value === undefined) {
return result
}
if (typeof value === 'string' && !value.length) {
return result
}
}
var message = this._message
if (rules === undefined) {
return message['default']
}
for (var i = 0; i < rules.length; i++) {
let rule = rules[i]
let vt = this._getValidateType(rule)
Object.assign(rule, {
label: fieldValue.label || `["${fieldKey}"]`
})
if (RuleValidatorHelper[vt]) {
result = RuleValidatorHelper[vt](rule, value, message)
if (result != null) {
break
}
}
if (rule.validateExpr) {
let now = Date.now()
let resultExpr = rule.validateExpr(value, allData, now)
if (resultExpr === false) {
result = this._getMessage(rule, rule.errorMessage || this._message['default'])
break
}
}
if (rule.validateFunction) {
result = await this.validateFunction(rule, value, data, allData, vt)
if (result !== null) {
break
}
}
}
if (result !== null) {
result = message.TAG + result
}
return result
}
async validateFunction(rule, value, data, allData, vt) {
let result = null
try {
let callbackMessage = null
const res = await rule.validateFunction(rule, value, allData || data, (message) => {
callbackMessage = message
})
if (callbackMessage || (typeof res === 'string' && res) || res === false) {
result = this._getMessage(rule, callbackMessage || res, vt)
}
} catch (e) {
result = this._getMessage(rule, e.message, vt)
}
return result
}
_getMessage(rule, message, vt) {
return formatMessage(rule, message || rule.errorMessage || this._message[vt] || message['default'])
}
_getValidateType(rule) {
var result = ''
if (rule.required) {
result = 'required'
} else if (rule.format) {
result = 'format'
} else if (rule.arrayType) {
result = 'arrayTypeFormat'
} else if (rule.range) {
result = 'range'
} else if (rule.maximum !== undefined || rule.minimum !== undefined) {
result = 'rangeNumber'
} else if (rule.maxLength !== undefined || rule.minLength !== undefined) {
result = 'rangeLength'
} else if (rule.pattern) {
result = 'pattern'
} else if (rule.validateFunction) {
result = 'validateFunction'
}
return result
}
}
const RuleValidatorHelper = {
required(rule, value, message) {
if (rule.required && isEmptyValue(value, rule.format || typeof value)) {
return formatMessage(rule, rule.errorMessage || message.required);
}
return null
},
range(rule, value, message) {
const {
range,
errorMessage
} = rule;
let list = new Array(range.length);
for (let i = 0; i < range.length; i++) {
const item = range[i];
if (types.object(item) && item.value !== undefined) {
list[i] = item.value;
} else {
list[i] = item;
}
}
let result = false
if (Array.isArray(value)) {
result = (new Set(value.concat(list)).size === list.length);
} else {
if (list.indexOf(value) > -1) {
result = true;
}
}
if (!result) {
return formatMessage(rule, errorMessage || message['enum']);
}
return null
},
rangeNumber(rule, value, message) {
if (!types.number(value)) {
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
}
let {
minimum,
maximum,
exclusiveMinimum,
exclusiveMaximum
} = rule;
let min = exclusiveMinimum ? value <= minimum : value < minimum;
let max = exclusiveMaximum ? value >= maximum : value > maximum;
if (minimum !== undefined && min) {
return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMinimum ?
'exclusiveMinimum' : 'minimum'
])
} else if (maximum !== undefined && max) {
return formatMessage(rule, rule.errorMessage || message['number'][exclusiveMaximum ?
'exclusiveMaximum' : 'maximum'
])
} else if (minimum !== undefined && maximum !== undefined && (min || max)) {
return formatMessage(rule, rule.errorMessage || message['number'].range)
}
return null
},
rangeLength(rule, value, message) {
if (!types.string(value) && !types.array(value)) {
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
}
let min = rule.minLength;
let max = rule.maxLength;
let val = value.length;
if (min !== undefined && val < min) {
return formatMessage(rule, rule.errorMessage || message['length'].minLength)
} else if (max !== undefined && val > max) {
return formatMessage(rule, rule.errorMessage || message['length'].maxLength)
} else if (min !== undefined && max !== undefined && (val < min || val > max)) {
return formatMessage(rule, rule.errorMessage || message['length'].range)
}
return null
},
pattern(rule, value, message) {
if (!types['pattern'](rule.pattern, value)) {
return formatMessage(rule, rule.errorMessage || message.pattern.mismatch);
}
return null
},
format(rule, value, message) {
var customTypes = Object.keys(types);
var format = FORMAT_MAPPING[rule.format] ? FORMAT_MAPPING[rule.format] : (rule.format || rule.arrayType);
if (customTypes.indexOf(format) > -1) {
if (!types[format](value)) {
return formatMessage(rule, rule.errorMessage || message.typeError);
}
}
return null
},
arrayTypeFormat(rule, value, message) {
if (!Array.isArray(value)) {
return formatMessage(rule, rule.errorMessage || message.typeError);
}
for (let i = 0; i < value.length; i++) {
const element = value[i];
let formatResult = this.format(rule, element, message)
if (formatResult !== null) {
return formatResult
}
}
return null
}
}
class SchemaValidator extends RuleValidator {
constructor(schema, options) {
super(SchemaValidator.message);
this._schema = schema
this._options = options || null
}
updateSchema(schema) {
this._schema = schema
}
async validate(data, allData) {
let result = this._checkFieldInSchema(data)
if (!result) {
result = await this.invokeValidate(data, false, allData)
}
return result.length ? result[0] : null
}
async validateAll(data, allData) {
let result = this._checkFieldInSchema(data)
if (!result) {
result = await this.invokeValidate(data, true, allData)
}
return result
}
async validateUpdate(data, allData) {
let result = this._checkFieldInSchema(data)
if (!result) {
result = await this.invokeValidateUpdate(data, false, allData)
}
return result.length ? result[0] : null
}
async invokeValidate(data, all, allData) {
let result = []
let schema = this._schema
for (let key in schema) {
let value = schema[key]
let errorMessage = await this.validateRule(key, value, data[key], data, allData)
if (errorMessage != null) {
result.push({
key,
errorMessage
})
if (!all) break
}
}
return result
}
async invokeValidateUpdate(data, all, allData) {
let result = []
for (let key in data) {
let errorMessage = await this.validateRule(key, this._schema[key], data[key], data, allData)
if (errorMessage != null) {
result.push({
key,
errorMessage
})
if (!all) break
}
}
return result
}
_checkFieldInSchema(data) {
var keys = Object.keys(data)
var keys2 = Object.keys(this._schema)
if (new Set(keys.concat(keys2)).size === keys2.length) {
return ''
}
var noExistFields = keys.filter((key) => {
return keys2.indexOf(key) < 0;
})
var errorMessage = formatMessage({
field: JSON.stringify(noExistFields)
}, SchemaValidator.message.TAG + SchemaValidator.message['defaultInvalid'])
return [{
key: 'invalid',
errorMessage
}]
}
}
function Message() {
return {
TAG: "",
default: '验证错误',
defaultInvalid: '提交的字段{field}在数据库中并不存在',
validateFunction: '验证无效',
required: '{label}必填',
'enum': '{label}超出范围',
timestamp: '{label}格式无效',
whitespace: '{label}不能为空',
typeError: '{label}类型无效',
date: {
format: '{label}日期{value}格式无效',
parse: '{label}日期无法解析,{value}无效',
invalid: '{label}日期{value}无效'
},
length: {
minLength: '{label}长度不能少于{minLength}',
maxLength: '{label}长度不能超过{maxLength}',
range: '{label}必须介于{minLength}和{maxLength}之间'
},
number: {
minimum: '{label}不能小于{minimum}',
maximum: '{label}不能大于{maximum}',
exclusiveMinimum: '{label}不能小于等于{minimum}',
exclusiveMaximum: '{label}不能大于等于{maximum}',
range: '{label}必须介于{minimum}and{maximum}之间'
},
pattern: {
mismatch: '{label}格式不匹配'
}
};
}
SchemaValidator.message = new Message();
export default SchemaValidator

View File

@ -0,0 +1,88 @@
{
"id": "uni-forms",
"displayName": "uni-forms 表单",
"version": "1.4.9",
"description": "由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据",
"keywords": [
"uni-ui",
"表单",
"校验",
"表单校验",
"表单验证"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-icons"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@ -0,0 +1,23 @@
## Forms 表单
> **组件名uni-forms**
> 代码块: `uForms`、`uni-forms-item`
> 关联组件:`uni-forms-item`、`uni-easyinput`、`uni-data-checkbox`、`uni-group`。
uni-app的内置组件已经有了 `<form>`组件,用于提交表单内容。
然而几乎每个表单都需要做表单验证,为了方便做表单验证,减少重复开发,`uni ui` 又基于 `<form>`组件封装了 `<uni-forms>`组件,内置了表单验证功能。
`<uni-forms>` 提供了 `rules`属性来描述校验规则、`<uni-forms-item>`子组件来包裹具体的表单项,以及给原生或三方组件提供了 `binddata()` 来设置表单值。
每个要校验的表单项不管input还是checkbox都必须放在`<uni-forms-item>`组件中,且一个`<uni-forms-item>`组件只能放置一个表单项。
`<uni-forms-item>`组件内部预留了显示error message的区域默认是在表单项的底部。
另外,`<uni-forms>`组件下面的各个表单项,可以通过`<uni-group>`包裹为不同的分组。同一`<uni-group>`下的不同表单项目将聚拢在一起同其他group保持垂直间距。`<uni-group>`仅影响视觉效果。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-forms)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"sources":["uni-app:///main.js"],"names":["wx","__webpack_require_UNI_MP_PLUGIN__","__webpack_require__","createPage","Page"],"mappings":";;;;;;;;;;;;;AAAA;AAGA;AACA;AAHA;AACAA,EAAE,CAACC,iCAAiC,GAAGC,mBAAmB;AAG1DC,UAAU,CAACC,eAAI,CAAC,C","file":"pageTwo/pageTwo/login/report.js","sourcesContent":["import 'uni-pages';\n// @ts-ignore\nwx.__webpack_require_UNI_MP_PLUGIN__ = __webpack_require__;\nimport Vue from 'vue'\nimport Page from './pageTwo/pageTwo/login/report.vue'\ncreatePage(Page)"],"sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"sources":["uni-app:///main.js"],"names":["wx","__webpack_require_UNI_MP_PLUGIN__","__webpack_require__","createPage","Page"],"mappings":";;;;;;;;;;;;;AAAA;AAGA;AACA;AAHA;AACAA,EAAE,CAACC,iCAAiC,GAAGC,mBAAmB;AAG1DC,UAAU,CAACC,eAAI,CAAC,C","file":"pageTwo/report/report.js","sourcesContent":["import 'uni-pages';\n// @ts-ignore\nwx.__webpack_require_UNI_MP_PLUGIN__ = __webpack_require__;\nimport Vue from 'vue'\nimport Page from './pageTwo/report/report.vue'\ncreatePage(Page)"],"sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -261,7 +261,7 @@ var _default = {
}
console.log("options", options);
uni.setNavigationBarTitle({
title: this.type == 3 ? "商品信息" : this.active == 8 ? '发布供货' : '我的需求'
title: this.type == 3 ? "发布商品" : this.type == 8 ? '发布供货' : '发布采购'
});
},
methods: {
@ -351,6 +351,7 @@ var _default = {
handlecolse: function handlecolse() {
this.content.province = "";
this.content.city = "";
this.content.area = "";
},
EditInfo: function EditInfo(data) {
var that = this;
@ -407,8 +408,8 @@ var _default = {
handleGetRegion: function handleGetRegion(ite) {
console.log("省市区", ite);
this.content.province = ite[0].name;
this.content.city = ite[1].name == '全部' ? '' : ite[1].name;
// this.content.area = ite[2].name
this.content.city = ite[1].name;
this.content.area = ite[2].name;
},
// 所属行业
changeIndustry: function changeIndustry(e) {

View File

@ -105,20 +105,9 @@ var render = function () {
var g0 = _vm.fimages.length
var g1 = _vm.HomeContent && _vm.centerList.length
var g2 = _vm.list.length
var g3 = g2 ? _vm.list.length : null
var g4 = g2 && g3 > 5 ? _vm.list.slice(0, 5) : null
var g3 = _vm.newsList.length
var g4 = _vm.newsList.length
var g5 = _vm.newsList.length
var g6 = _vm.newsList.length
var g7 = _vm.newsList.length
if (!_vm._isMounted) {
_vm.e0 = function ($event, item) {
var _temp = arguments[arguments.length - 1].currentTarget.dataset,
_temp2 = _temp.eventParams || _temp["event-params"],
item = _temp2.item
var _temp, _temp2
return _vm.handleDetail(item)
}
}
_vm.$mp.data = Object.assign(
{},
{
@ -129,8 +118,6 @@ var render = function () {
g3: g3,
g4: g4,
g5: g5,
g6: g6,
g7: g7,
},
}
)
@ -306,9 +293,10 @@ var _default = {
var that = this;
that.$model.getVipList({
pageNo: 1,
pageSize: 6
pageSize: 100
}).then(function (res) {
if (res.code == 0) {
console.log("风采", res.data.rows);
_this2.list = res.data.rows;
}
});

View File

@ -1 +1 @@
<view class="content data-v-57280228"><block wx:if="{{token}}"><view class="head data-v-57280228"><piker-search vue-id="8dd740cc-1" placeholder="找客户/找产品/找供应" width="60" data-event-opts="{{[['^handleSearch',[['handleSearch']]]]}}" bind:handleSearch="__e" class="data-v-57280228" bind:__l="__l"></piker-search>--><view class="fangke data-v-57280228"><icon class="iconfont icon-remen data-v-57280228"></icon><text class="data-v-57280228">{{"今日访客:"+todayviewer+"人"}}</text></view></view></block><block wx:else><view data-event-opts="{{[['tap',[['handleLogin',['$event']]]]]}}" class="login data-v-57280228" bindtap="__e">登录后查看更多内容资讯,点击此处<text class="data-v-57280228">登录</text></view></block><view class="tips data-v-57280228" style="{{'margin:'+(!token?'0':'110rpx 0 10px')+';'}}"><block wx:if="{{token&&!mobile}}"><text data-event-opts="{{[['tap',[['navTo',['/pageTwo/me/company']]]]]}}" bindtap="__e" class="data-v-57280228">请尽快完善企业信息</text></block></view><view class="f_banner data-v-57280228"><block wx:if="{{$root.g0}}"><view class="data-v-57280228"><swiper class="swiper data-v-57280228" indicator-dots="true" autoplay="true"><block wx:for="{{fimages}}" wx:for-item="image" wx:for-index="index" wx:key="index"><swiper-item data-event-opts="{{[['tap',[['detail',['$0',5],[[['fimages','',index,'id']]]]]]]}}" bindtap="__e" class="data-v-57280228"><image src="{{image.headimg}}" class="data-v-57280228"></image></swiper-item></block></swiper></view></block></view><view class="notice data-v-57280228"><text class="data-v-57280228">头条</text><swiper class="swiper data-v-57280228" vertical="true" autoplay="true"><block wx:for="{{notices}}" wx:for-item="item" wx:for-index="index" wx:key="index"><swiper-item data-event-opts="{{[['tap',[['detail',['$0',6],[[['notices','',index,'id']]]]]]]}}" bindtap="__e" class="data-v-57280228"><view class="overflow data-v-57280228">{{item.title}}</view></swiper-item></block></swiper></view><view class="tools data-v-57280228"><block wx:for="{{navbarlist}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view data-event-opts="{{[['tap',[['handlePath',[index,'$0'],[[['navbarlist','',index,'link']]]]]]]}}" class="item data-v-57280228" bindtap="__e"><image src="{{item.image}}" class="data-v-57280228"></image><text class="data-v-57280228">{{item.name}}</text></view></block></view><view class="f_banner data-v-57280228" style="margin-top:15px;"><block wx:if="{{$root.g1}}"><view class="data-v-57280228"><swiper class="swiper data-v-57280228" autoplay="true"><block wx:for="{{centerList}}" wx:for-item="image" wx:for-index="index" wx:key="index"><swiper-item data-event-opts="{{[['tap',[['detail',['$0',5],[[['centerList','',index,'id']]]]]]]}}" bindtap="__e" class="data-v-57280228"><image src="{{image.headimg}}" class="data-v-57280228"></image></swiper-item></block></swiper></view></block></view><block wx:if="{{$root.g2}}"><view class="tools fengcai data-v-57280228"><view data-event-opts="{{[['tap',[['navTo',['/pages/index/fengCai']]]]]}}" class="title data-v-57280228" bindtap="__e"><text class="ml-10 data-v-57280228">领导风采</text><text class="mr-10 data-v-57280228">查看更多></text></view><block wx:for="{{$root.g3>5?$root.g4:list}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view data-event-opts="{{[['tap',[['e0',['$event']]]]]}}" data-event-params="{{({item})}}" class="item mt-15 data-v-57280228" bindtap="__e"><image src="{{item.avatar}}" mode="aspectFill" class="data-v-57280228"></image><view class="name data-v-57280228">{{item.name}}</view><view class="post data-v-57280228">{{item.posname}}</view></view></block></view></block><view class="zixun data-v-57280228"><view data-event-opts="{{[['tap',[['navTo',['/pageTwo/news/list?type=1']]]]]}}" class="title mt-10 data-v-57280228" bindtap="__e"><text class="data-v-57280228">资讯活动</text><block wx:if="{{$root.g5}}"><text class="data-v-57280228">查看更多></text></block></view><block wx:if="{{$root.g6}}"><list vue-id="8dd740cc-2" isAddress="{{1}}" list="{{newsList}}" class="data-v-57280228" bind:__l="__l"></list></block><block wx:if="{{!$root.g7}}"><view class="nolist data-v-57280228" style="margin-top:15px;"><image src="/static/none.png" class="data-v-57280228"></image><text class="data-v-57280228">暂无数据</text></view></block></view><message vue-id="8dd740cc-3" class="data-v-57280228" bind:__l="__l"></message></view>
<view class="content data-v-57280228"><block wx:if="{{token}}"><view class="head data-v-57280228"><piker-search vue-id="8dd740cc-1" placeholder="找客户/找产品/找供应" width="60" data-event-opts="{{[['^handleSearch',[['handleSearch']]]]}}" bind:handleSearch="__e" class="data-v-57280228" bind:__l="__l"></piker-search>--><view class="fangke data-v-57280228"><icon class="iconfont icon-remen data-v-57280228"></icon><text class="data-v-57280228">{{"今日访客:"+todayviewer+"人"}}</text></view></view></block><block wx:else><view data-event-opts="{{[['tap',[['handleLogin',['$event']]]]]}}" class="login data-v-57280228" bindtap="__e">登录后查看更多内容资讯,点击此处<text class="data-v-57280228">登录</text></view></block><view class="tips data-v-57280228" style="{{'margin:'+(!token?'0':'110rpx 0 10px')+';'}}"><block wx:if="{{token&&!mobile}}"><text data-event-opts="{{[['tap',[['navTo',['/pageTwo/me/company']]]]]}}" bindtap="__e" class="data-v-57280228">请尽快完善企业信息</text></block></view><view class="f_banner data-v-57280228"><block wx:if="{{$root.g0}}"><view class="data-v-57280228"><swiper class="swiper data-v-57280228" indicator-dots="true" autoplay="true"><block wx:for="{{fimages}}" wx:for-item="image" wx:for-index="index" wx:key="index"><swiper-item data-event-opts="{{[['tap',[['detail',['$0',5],[[['fimages','',index,'id']]]]]]]}}" bindtap="__e" class="data-v-57280228"><image src="{{image.headimg}}" class="data-v-57280228"></image></swiper-item></block></swiper></view></block></view><view class="notice data-v-57280228"><text class="data-v-57280228">头条</text><swiper class="swiper data-v-57280228" vertical="true" autoplay="true"><block wx:for="{{notices}}" wx:for-item="item" wx:for-index="index" wx:key="index"><swiper-item data-event-opts="{{[['tap',[['detail',['$0',6],[[['notices','',index,'id']]]]]]]}}" bindtap="__e" class="data-v-57280228"><view class="overflow data-v-57280228">{{item.title}}</view></swiper-item></block></swiper></view><view class="tools data-v-57280228"><block wx:for="{{navbarlist}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view data-event-opts="{{[['tap',[['handlePath',[index,'$0'],[[['navbarlist','',index,'link']]]]]]]}}" class="item data-v-57280228" bindtap="__e"><image src="{{item.image}}" class="data-v-57280228"></image><text class="data-v-57280228">{{item.name}}</text></view></block></view><view class="f_banner data-v-57280228" style="margin-top:15px;"><block wx:if="{{$root.g1}}"><view class="data-v-57280228"><swiper class="swiper data-v-57280228" autoplay="true"><block wx:for="{{centerList}}" wx:for-item="image" wx:for-index="index" wx:key="index"><swiper-item data-event-opts="{{[['tap',[['detail',['$0',5],[[['centerList','',index,'id']]]]]]]}}" bindtap="__e" class="data-v-57280228"><image src="{{image.headimg}}" class="data-v-57280228"></image></swiper-item></block></swiper></view></block></view><block wx:if="{{$root.g2}}"><view class="tools fengcai data-v-57280228"><view data-event-opts="{{[['tap',[['navTo',['/pages/index/fengCai']]]]]}}" class="title data-v-57280228" bindtap="__e"><text class="ml-10 data-v-57280228">领导风采</text><text class="mr-10 data-v-57280228">查看更多></text></view><swiper class="swiper data-v-57280228" display-multiple-items="5" autoplay="true" circular="true" interval="3000"><block wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="index"><swiper-item data-event-opts="{{[['tap',[['handleDetail',['$0'],[[['list','',index]]]]]]]}}" bindtap="__e" class="data-v-57280228"><view class="item mt-15 data-v-57280228"><image src="{{item.avatar}}" mode="aspectFill" class="data-v-57280228"></image><view class="name data-v-57280228">{{item.name}}</view><view class="post data-v-57280228">{{item.posname}}</view></view></swiper-item></block></swiper></view></block><view class="zixun data-v-57280228"><view data-event-opts="{{[['tap',[['navTo',['/pageTwo/news/list?type=1']]]]]}}" class="title mt-10 data-v-57280228" bindtap="__e"><text class="data-v-57280228">资讯活动</text><block wx:if="{{$root.g3}}"><text class="data-v-57280228">查看更多></text></block></view><block wx:if="{{$root.g4}}"><list vue-id="8dd740cc-2" isAddress="{{1}}" list="{{newsList}}" class="data-v-57280228" bind:__l="__l"></list></block><block wx:if="{{!$root.g5}}"><view class="nolist data-v-57280228" style="margin-top:15px;"><image src="/static/none.png" class="data-v-57280228"></image><text class="data-v-57280228">暂无数据</text></view></block></view><message vue-id="8dd740cc-3" class="data-v-57280228" bind:__l="__l"></message></view>

View File

@ -150,8 +150,15 @@
color: #000;
justify-content: space-between;
}
.fengcai.data-v-57280228 {
padding-bottom: 5px;
}
.fengcai.data-v-57280228 swiper {
width: 100%;
height: 240rpx;
}
.fengcai .item.data-v-57280228 {
width: 20%;
width: 100%;
}
.fengcai .item image.data-v-57280228 {
width: 50px;

View File

@ -19,7 +19,7 @@
"condition": false
},
"compileType": "miniprogram",
"libVersion": "3.0.0",
"libVersion": "",
"appid": "wxbbddd1888da43ab0",
"projectname": "intelligentGroup",
"condition": {

View File

@ -9,12 +9,13 @@
"list": [
{
"name": "",
"pathName": "pageTwo/login/login",
"pathName": "pageTwo/login/editPassword",
"query": "",
"launchMode": "default",
"scene": null
}
]
}
}
},
"libVersion": "3.2.2"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB