Commit 003f471f authored by lizhan's avatar lizhan

📝 【TASK-20240806-03】TASK:APP地址页面静态页面完成、组件改动

全部地址、添加、修改页面;header组件修改,增加右侧加号;引入uni-form表单组件,uni-easyinput输入框增强组件
parent d2984a5e
.header-toper{
.header-toper {
width: 100%;
height: 80upx;
background-image: url(../../static/img/top.png);
......@@ -11,7 +11,8 @@
z-index: 99;
background-color: var(--bColor);
}
.header-toper-title{
.header-toper-title {
position: relative;
display: flex;
justify-content: center;
......@@ -20,7 +21,8 @@
color: var(--c0);
font-weight: 700;
}
.header-toper-title image{
.header-toper-title image {
width: 48upx;
height: 44upx;
position: absolute;
......
......@@ -4,24 +4,33 @@
<!-- <view class="start-bar"></view> -->
<view class="header-toper-title">
<image src="../../static/img/back.png" mode="" @click="$request.backGo"></image>
<text>{{title}}</text>
<text>{{ title }}</text>
<image
v-if="rightBtn"
src="../../static/img/add.png"
mode=""
@click="$emit('rightBtnClick')"
></image>
</view>
</view>
</view>
</template>
<script>
export default {
export default {
props: {
title: String,
rightBtn: {
type: Boolean,
default: false
}
},
data() {
return {
}
return {}
},
methods: {
}
}
methods: {}
}
</script>
<style>
/* @import url(./index.css); */
/* 页面css在static css main.css里面 */
/* @import url(./index.css); */
</style>
This diff is collapsed.
<template>
<view>
<dHeader
:title="$lang.lang.addressInfo.info"
:right-btn="true"
@rightBtnClick="toAddressAdd"
></dHeader>
<view class="container">
<view class="address-list">
<view class="address-item" v-for="item in 3" :key="item">
<view class="item-header">
<view class="item-name">张三</view>
<view class="item-phone">+86 18888888888</view>
</view>
<view class="item-content">
辽宁省大连市甘井子区广贤路56号星光大道甘井子区广贤路56号星光大道
</view>
<view class="item-footer">
<view
class="item-default"
@click="bindCheck($event, item)"
:class="{ 'item-default-active': check == item }"
>
<label class="radio"
><radio
class="radio"
color="#ff4d4f"
value="r1"
:value="item + ''"
:checked="check == item"
/>设为默认地址</label
>
</view>
<view class="item-footer-right">
<view class="right-box" @click="toEditAddress">
<image class="item-img" src="../../static/img/edit.png"></image>
编辑</view
>
<view class="right-box">
<image class="item-img" src="../../static/img/delete_pail.png"></image>
删除</view
>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import dHeader from '../../components/dHeader/index.vue'
export default {
components: {
dHeader
},
data() {
return {
check: 1
}
},
methods: {
toAddressAdd() {
uni.navigateTo({
url: '/pages/address_add/address_add'
})
},
toEditAddress() {
uni.navigateTo({
url: '/pages/address_edit/address_edit'
})
},
// 切换默认地址
bindCheck(e, item) {
this.check = item
}
}
}
</script>
<style>
@import url(../../static/css/address.css);
</style>
<template>
<view>
<dHeader :title="$lang.lang.addressInfo.addInfo"></dHeader>
<view class="container">
<uni-forms ref="form" :model="form" :label-width="80" :rules="rules">
<uni-forms-item :label="$lang.lang.addressInfo.consignee" required name="consignee">
<uni-easyinput
class="input"
:trim="true"
:inputBorder="false"
v-model="form.consignee"
:placeholder="$lang.lang.notices.consignee"
/>
</uni-forms-item>
<uni-forms-item :label="$lang.lang.addressInfo.phone" required name="phone">
<view class="phone-box">
<view class="phone-code">+86</view>
<uni-easyinput
class="input"
:trim="true"
:inputBorder="false"
v-model.trim="form.phone"
:placeholder="$lang.lang.notices.phone"
/>
</view>
</uni-forms-item>
<uni-forms-item
class="item"
:label="$lang.lang.addressInfo.fullAddress"
required
name="fullAddress"
>
<view class="textarea-box">
<uni-easyinput
class="input"
type="textarea"
:trim="true"
autoHeight
:inputBorder="false"
:maxlength="100"
v-model.trim="form.fullAddress"
:placeholder="$lang.lang.notices.fullAddress"
>
</uni-easyinput>
<view class="placeholder">{{ $lang.lang.notices.fullAddressLength }}</view>
</view>
</uni-forms-item>
<view class="btn" @click="saveAddress">报存地址</view>
</uni-forms>
</view>
</view>
</template>
<script>
import dHeader from '../../components/dHeader/index.vue'
export default {
components: {
dHeader
},
data() {
return {
form: {
consignee: '',
phone: '',
fullAddress: ''
}
}
},
computed: {
rules() {
return {
consignee: {
rules: [{ required: true, errorMessage: this.$lang.lang.notices.consignee }]
},
phone: {
rules: [{ required: true, errorMessage: this.$lang.lang.notices.phone }]
},
fullAddress: {
rules: [
{ required: true, errorMessage: this.$lang.lang.notices.fullAddress },
{ maxLength: 100, errorMessage: this.$lang.lang.notices.fullAddressLength }
]
}
}
}
},
methods: {
saveAddress() {
// console.log(this.form)
this.$refs.form.validate().then((res) => {
console.log(res)
})
}
}
}
</script>
<style>
page {
padding-top: 190upx;
}
.uni-forms {
padding: 0 48upx;
box-sizing: border-box;
}
.uni-forms-item {
padding: 0 24upx;
margin-bottom: 44upx;
width: 100%;
align-items: center;
min-height: 80upx;
box-sizing: border-box;
border-radius: 12upx;
background-color: #fff;
}
.item {
align-items: start;
}
.input {
font-size: 24upx;
}
.textarea-box {
padding: 0 0 30upx;
}
.placeholder {
position: absolute;
bottom: 8upx;
right: 0;
font-size: 24upx;
color: #b3b3b3;
}
.phone-box {
display: flex;
align-items: center;
}
.phone-code {
margin-right: 10upx;
padding-right: 10upx;
border-right: 1px solid #e6e6e6;
font-size: 24upx;
color: #000;
}
.btn {
width: 100%;
height: 80upx;
line-height: 80upx;
text-align: center;
background-color: #3d6ef6;
color: #fff;
border-radius: 80upx;
margin-top: 40upx;
}
::v-deep .uni-forms-item__label {
font-size: 28upx !important;
font-weight: 500 !important;
color: #000;
}
::v-deep .uni-easyinput__content-input {
padding-left: 0 !important;
}
::v-deep .uni-easyinput__content-textarea {
height: 100upx;
min-height: 100upx;
/* #ifndef APP-NVUE */
min-height: 100upx;
width: auto;
/* #endif */
}
</style>
<template>
<view>
<dHeader :title="$lang.lang.addressInfo.editInfo"></dHeader>
<view class="container">
<uni-forms ref="form" :model="form" :label-width="80" :rules="rules">
<uni-forms-item :label="$lang.lang.addressInfo.consignee" required name="consignee">
<uni-easyinput
class="input"
:trim="true"
:inputBorder="false"
v-model="form.consignee"
:placeholder="$lang.lang.notices.consignee"
/>
</uni-forms-item>
<uni-forms-item :label="$lang.lang.addressInfo.phone" required name="phone">
<view class="phone-box">
<view class="phone-code">+86</view>
<uni-easyinput
class="input"
:trim="true"
:inputBorder="false"
v-model.trim="form.phone"
:placeholder="$lang.lang.notices.phone"
/>
</view>
</uni-forms-item>
<uni-forms-item
class="item"
:label="$lang.lang.addressInfo.fullAddress"
required
name="fullAddress"
>
<view class="textarea-box">
<uni-easyinput
class="input"
type="textarea"
:trim="true"
autoHeight
:inputBorder="false"
:maxlength="100"
v-model.trim="form.fullAddress"
:placeholder="$lang.lang.notices.fullAddress"
>
</uni-easyinput>
<view class="placeholder">{{ $lang.lang.notices.fullAddressLength }}</view>
</view>
</uni-forms-item>
<view class="btn" @click="saveAddress">报存地址</view>
</uni-forms>
</view>
</view>
</template>
<script>
import dHeader from '../../components/dHeader/index.vue'
export default {
components: {
dHeader
},
data() {
return {
form: {
consignee: '',
phone: '',
fullAddress: ''
}
}
},
computed: {
rules() {
return {
consignee: {
rules: [{ required: true, errorMessage: this.$lang.lang.notices.consignee }]
},
phone: {
rules: [{ required: true, errorMessage: this.$lang.lang.notices.phone }]
},
fullAddress: {
rules: [
{ required: true, errorMessage: this.$lang.lang.notices.fullAddress },
{ maxLength: 100, errorMessage: this.$lang.lang.notices.fullAddressLength }
]
}
}
}
},
methods: {
saveAddress() {
// console.log(this.form)
this.$refs.form.validate().then((res) => {
console.log(res)
})
}
}
}
</script>
<style>
page {
padding-top: 190upx;
}
.uni-forms {
padding: 0 48upx;
box-sizing: border-box;
}
.uni-forms-item {
padding: 0 24upx;
margin-bottom: 44upx;
width: 100%;
align-items: center;
min-height: 80upx;
box-sizing: border-box;
border-radius: 12upx;
background-color: #fff;
}
.item {
align-items: start;
}
.input {
font-size: 24upx;
}
.textarea-box {
padding: 0 0 30upx;
}
.placeholder {
position: absolute;
bottom: 8upx;
right: 0;
font-size: 24upx;
color: #b3b3b3;
}
.phone-box {
display: flex;
align-items: center;
}
.phone-code {
margin-right: 10upx;
padding-right: 10upx;
border-right: 1px solid #e6e6e6;
font-size: 24upx;
color: #000;
}
.btn {
width: 100%;
height: 80upx;
line-height: 80upx;
text-align: center;
background-color: #3d6ef6;
color: #fff;
border-radius: 80upx;
margin-top: 40upx;
}
::v-deep .uni-forms-item__label {
font-size: 28upx !important;
font-weight: 500 !important;
color: #000;
}
::v-deep .uni-easyinput__content-input {
padding-left: 0 !important;
}
::v-deep .uni-easyinput__content-textarea {
height: 100upx;
min-height: 100upx;
/* #ifndef APP-NVUE */
min-height: 100upx;
width: auto;
/* #endif */
}
</style>
......@@ -113,7 +113,7 @@
<image class="rgt" src="../../static/img/rgt.png" mode=""></image>
</view>
</view>
<view class="items-v">
<view class="items-v" @click="toAddress">
<image src=".../../static/img/site_address.png" mode=""></image>
<view class="items-v-it noborder">
<text>{{ $lang.lang.site.address }}</text>
......@@ -589,6 +589,12 @@ export default {
}
}
})
},
// 跳转地址信息
toAddress() {
uni.navigateTo({
url: '../address/address'
})
}
}
}
......
page {
/* #ifdef H5 */
padding-top: 140upx;
/* #endif */
/* #ifdef APP-PLUS */
padding-top: calc(var(--status-bar-height) + 100upx);
/* #endif */
}
.container {
padding: 32upx 32upx 0;
}
.address-list {
width: 100%;
}
.address-item {
background-color: #fff;
border-radius: 16upx;
padding: 28upx 0 20upx;
margin-bottom: 32upx;
box-shadow: 0 4upx 24upx 0 rgba(0, 0, 0, 0.1);
}
.item-header {
padding: 0 32upx;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16upx;
}
.item-name {
font-size: 32upx;
font-weight: 500;
}
.item-phone {
font-size: 28upx;
font-weight: 500;
}
.item-content {
padding: 0 32upx;
font-size: 28upx;
color: #b3b3b3;
margin-bottom: 16upx;
}
.item-footer {
padding: 20upx 32upx 0;
border-top: 2upx solid #b3b3b3;
display: flex;
font-size: 28upx;
justify-content: space-between;
align-items: center;
}
.item-default {
color: #666;
padding: 8upx 16upx;
}
.item-default-active {
color: #ff4d4f;
}
.item-footer-right {
display: flex;
align-items: center;
}
.radio {
transform: scale(0.7);
}
.right-box {
color: #666;
display: flex;
align-items: center;
margin-left: 20upx;
}
.item-img {
width: 40upx;
height: 40upx;
margin-right: 8upx;
}
:root{
:root {
--bColor: #F5F5F5;
--cf7: #F7F7F7;
--cfb: #FBFBFB;
......@@ -25,15 +25,18 @@
--f32: 32upx;
--f40: 40upx;
}
page{
page {
background-color: var(--bColor);
font-size: var(--f30);
}
view{
view {
word-break: break-word;
}
/* #ifdef H5*/
.header-toper{
.header-toper {
width: 100%;
background-image: url(@/static/img/top.png);
background-repeat: no-repeat;
......@@ -45,9 +48,10 @@ view{
z-index: 99;
background-color: var(--bColor);
}
/* #endif */
/* #ifdef APP-PLUS*/
.header-toper{
.header-toper {
width: 100%;
height: 60upx;
background-image: url(@/static/img/top.png);
......@@ -61,8 +65,9 @@ view{
z-index: 99;
background-color: var(--bColor);
}
/* #endif */
.header-toper-title{
.header-toper-title {
position: relative;
display: flex;
justify-content: center;
......@@ -71,14 +76,21 @@ view{
color: var(--c0);
font-weight: 700;
}
.header-toper-title image{
.header-toper-title image {
width: 48upx;
height: 44upx;
position: absolute;
left: 0;
padding: 40upx;
}
/* .start-bar {
.header-toper-title image:last-child {
left: auto;
right: 0;
}
/* .start-bar {
width: 100%;
height: var(--status-bar-height);
} */
......@@ -132,7 +132,9 @@ export default {
nofile: 'The upload file format is incorrect',
loading: 'loading......',
country: 'Please select a country',
city: 'Please select a city'
city: 'Please select a city',
fullAddress: 'Please enter the detailed address',
fullAddressLength: 'Enter up to 100 words'
},
auth: {
auth: 'Real-name certification',
......@@ -151,6 +153,14 @@ export default {
intNotice4: 'weight must be greater than 0',
intNotice5: 'works must be greater than 0'
},
addressInfo: {
info: 'All addresses',
addInfo: 'New address for additional shipments',
editInfo: 'Edit the shipping address',
consignee: 'consignee',
phone: 'phone number',
fullAddress: 'Full address'
},
boxException: {
exception: 'excess cartons abormal',
exceptionless: 'Shortage abnormal',
......
......@@ -131,7 +131,9 @@ export default {
nofile: '上传文件格式不对',
loading: '加载中......',
country: '请选择国家',
city: '请选择城市'
city: '请选择城市',
fullAddress: '请输入详细地址',
fullAddressLength: '最多输入100字'
},
auth: {
auth: '实名认证',
......@@ -150,6 +152,14 @@ export default {
intNotice4: '重量必须大于0',
intNotice5: '货值必须大于0'
},
addressInfo: {
info: '全部地址',
addInfo: '新增收货地址',
editInfo: '编辑收货地址',
consignee: '收货人',
phone: '手机号',
fullAddress: '详细地址'
},
boxException: {
exception: '多箱异常',
exceptionless: '少箱异常',
......
## 1.1.19(2024-07-18)
- 修复 初始值传入 null 导致input报错的bug
## 1.1.18(2024-04-11)
- 修复 easyinput组件双向绑定问题
## 1.1.17(2024-03-28)
- 修复 在头条小程序下丢失事件绑定的问题
## 1.1.16(2024-03-20)
- 修复 在密码输入情况下 清除和小眼睛覆盖bug 在edge浏览器下显示双眼睛bug
## 1.1.15(2024-02-21)
- 新增 左侧插槽:left
## 1.1.14(2024-02-19)
- 修复 onBlur的emit传值错误
## 1.1.12(2024-01-29)
- 补充 adjust-position文档属性补充
## 1.1.11(2024-01-29)
- 补充 adjust-position属性传递值:(Boolean)当键盘弹起时,是否自动上推页面
## 1.1.10(2024-01-22)
- 去除 移除无用的log输出
## 1.1.9(2023-04-11)
- 修复 vue3 下 keyboardheightchange 事件报错的bug
## 1.1.8(2023-03-29)
- 优化 trim 属性默认值
## 1.1.7(2023-03-29)
- 新增 cursor-spacing 属性
## 1.1.6(2023-01-28)
- 新增 keyboardheightchange 事件,可监听键盘高度变化
## 1.1.5(2022-11-29)
- 优化 主题样式
## 1.1.4(2022-10-27)
- 修复 props 中背景颜色无默认值的bug
## 1.1.0(2022-06-30)
- 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容
- 新增 clear 事件,点击右侧叉号图标触发
- 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发
- 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等
## 1.0.5(2022-06-07)
- 优化 clearable 显示策略
## 1.0.4(2022-06-07)
- 优化 clearable 显示策略
## 1.0.3(2022-05-20)
- 修复 关闭图标某些情况下无法取消的 bug
## 1.0.2(2022-04-12)
- 修复 默认值不生效的 bug
## 1.0.1(2022-04-02)
- 修复 value 不能为 0 的 bug
## 1.0.0(2021-11-19)
- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-easyinput](https://uniapp.dcloud.io/component/uniui/uni-easyinput)
## 0.1.4(2021-08-20)
- 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
## 0.1.3(2021-08-11)
- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
## 0.1.2(2021-07-30)
- 优化 vue3 下事件警告的问题
## 0.1.1
- 优化 errorMessage 属性支持 Boolean 类型
## 0.1.0(2021-07-13)
- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 0.0.16(2021-06-29)
- 修复 confirmType 属性(仅 type="text" 生效)导致多行文本框无法换行的 bug
## 0.0.15(2021-06-21)
- 修复 passwordIcon 属性拼写错误的 bug
## 0.0.14(2021-06-18)
- 新增 passwordIcon 属性,当 type=password 时是否显示小眼睛图标
- 修复 confirmType 属性不生效的问题
## 0.0.13(2021-06-04)
- 修复 disabled 状态可清出内容的 bug
## 0.0.12(2021-05-12)
- 新增 组件示例地址
## 0.0.11(2021-05-07)
- 修复 input-border 属性不生效的问题
## 0.0.10(2021-04-30)
- 修复 ios 遮挡文字、显示一半的问题
## 0.0.9(2021-02-05)
- 调整为 uni_modules 目录规范
- 优化 兼容 nvue 页面
/**
* @desc 函数防抖
* @param func 目标函数
* @param wait 延迟执行毫秒数
* @param immediate true - 立即执行, false - 延迟执行
*/
export const debounce = function(func, wait = 1000, immediate = true) {
let timer;
return function() {
let context = this,
args = arguments;
if (timer) clearTimeout(timer);
if (immediate) {
let callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait);
if (callNow) func.apply(context, args);
} else {
timer = setTimeout(() => {
func.apply(context, args);
}, wait)
}
}
}
/**
* @desc 函数节流
* @param func 函数
* @param wait 延迟执行毫秒数
* @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发
*/
export const throttle = (func, wait = 1000, type = 1) => {
let previous = 0;
let timeout;
return function() {
let context = this;
let args = arguments;
if (type === 1) {
let now = Date.now();
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
} else if (type === 2) {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
}
{
"id": "uni-easyinput",
"displayName": "uni-easyinput 增强输入框",
"version": "1.1.19",
"description": "Easyinput 组件是对原生input组件的增强",
"keywords": [
"uni-ui",
"uniui",
"input",
"uni-easyinput",
"输入框"
],
"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",
"alipay": "n"
},
"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"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
\ No newline at end of file
### Easyinput 增强输入框
> **组件名:uni-easyinput**
> 代码块: `uEasyinput`
easyinput 组件是对原生input组件的增强 ,是专门为配合表单组件[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)而设计的,easyinput 内置了边框,图标等,同时包含 input 所有功能
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-easyinput)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
\ No newline at end of file
## 1.4.10(2023-11-03)
- 优化 labelWidth 描述错误
## 1.4.9(2023-02-10)
- 修复 required 参数无法动态绑定
## 1.4.8(2022-08-23)
- 优化 根据 rules 自动添加 required 的问题
## 1.4.7(2022-08-22)
- 修复 item 未设置 require 属性,rules 设置 require 后,星号也显示的 bug,详见:[https://ask.dcloud.net.cn/question/151540](https://ask.dcloud.net.cn/question/151540)
## 1.4.6(2022-07-13)
- 修复 model 需要校验的值没有声明对应字段时,导致第一次不触发校验的bug
## 1.4.5(2022-07-05)
- 新增 更多表单示例
- 优化 子表单组件过期提示的问题
- 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式
## 1.4.4(2022-07-04)
- 更新 删除组件日志
## 1.4.3(2022-07-04)
- 修复 由 1.4.0 引发的 label 插槽不生效的bug
## 1.4.2(2022-07-04)
- 修复 子组件找不到 setValue 报错的bug
## 1.4.1(2022-07-04)
- 修复 uni-data-picker 在 uni-forms-item 中报错的bug
- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
## 1.4.0(2022-06-30)
- 【重要】组件逻辑重构,部分用法用旧版本不兼容,请注意兼容问题
- 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力
- 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃
- 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效
- 新增 onFieldChange 方法,可以对子表单进行校验,可替代binddata方法
- 新增 子表单的 setRules 方法,配合自定义校验函数使用
- 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则
- 优化 动态表单校验方式,废弃拼接name的方式
## 1.3.3(2022-06-22)
- 修复 表单校验顺序无序问题
## 1.3.2(2021-12-09)
-
## 1.3.1(2021-11-19)
- 修复 label 插槽不生效的bug
## 1.3.0(2021-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.7(2021-08-13)
- 修复 没有添加校验规则的字段依然报错的Bug
## 1.2.6(2021-08-11)
- 修复 重置表单错误信息无法清除的问题
## 1.2.5(2021-08-11)
- 优化 组件文档
## 1.2.4(2021-08-11)
- 修复 表单验证只生效一次的问题
## 1.2.3(2021-07-30)
- 优化 vue3下事件警告的问题
## 1.2.2(2021-07-26)
- 修复 vue2 下条件编译导致destroyed生命周期失效的Bug
- 修复 1.2.1 引起的示例在小程序平台报错的Bug
## 1.2.1(2021-07-22)
- 修复 动态校验表单,默认值为空的情况下校验失效的Bug
- 修复 不指定name属性时,运行报错的Bug
- 优化 label默认宽度从65调整至70,使required为true且四字时不换行
- 优化 组件示例,新增动态校验示例代码
- 优化 组件文档,使用方式更清晰
## 1.2.0(2021-07-13)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.2(2021-06-25)
- 修复 pattern 属性在微信小程序平台无效的问题
## 1.1.1(2021-06-22)
- 修复 validate-trigger属性为submit且err-show-type属性为toast时不能弹出的Bug
## 1.1.0(2021-06-22)
- 修复 只写setRules方法而导致校验不生效的Bug
- 修复 由上个办法引发的错误提示文字错位的Bug
## 1.0.48(2021-06-21)
- 修复 不设置 label 属性 ,无法设置label插槽的问题
## 1.0.47(2021-06-21)
- 修复 不设置label属性,label-width属性不生效的bug
- 修复 setRules 方法与rules属性冲突的问题
## 1.0.46(2021-06-04)
- 修复 动态删减数据导致报错的问题
## 1.0.45(2021-06-04)
- 新增 modelValue 属性 ,value 即将废弃
## 1.0.44(2021-06-02)
- 新增 uni-forms-item 可以设置单独的 rules
- 新增 validate 事件增加 keepitem 参数,可以选择那些字段不过滤
- 优化 submit 事件重命名为 validate
## 1.0.43(2021-05-12)
- 新增 组件示例地址
## 1.0.42(2021-04-30)
- 修复 自定义检验器失效的问题
## 1.0.41(2021-03-05)
- 更新 校验器
- 修复 表单规则设置类型为 number 的情况下,值为0校验失败的Bug
## 1.0.40(2021-03-04)
- 修复 动态显示uni-forms-item的情况下,submit 方法获取值错误的Bug
## 1.0.39(2021-02-05)
- 调整为uni_modules目录规范
- 修复 校验器传入 int 等类型 ,返回String类型的Bug
This diff is collapsed.
/**
* 简单处理对象拷贝
* @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;
}
}
This diff is collapsed.
{
"id": "uni-forms",
"displayName": "uni-forms 表单",
"version": "1.4.10",
"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"
}
}
}
}
}
## 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
\ No newline at end of file
## 2.0.10(2024-06-07)
- 优化 uni-app x 中,size 属性的类型
## 2.0.9(2024-01-12)
fix: 修复图标大小默认值错误的问题
## 2.0.8(2023-12-14)
- 修复 项目未使用 ts 情况下,打包报错的bug
## 2.0.7(2023-12-14)
- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
## 2.0.6(2023-12-11)
- 优化 兼容老版本icon类型,如 top ,bottom 等
## 2.0.5(2023-12-11)
- 优化 兼容老版本icon类型,如 top ,bottom 等
## 2.0.4(2023-12-06)
- 优化 uni-app x 下示例项目图标排序
## 2.0.3(2023-12-06)
- 修复 nvue下引入组件报错的bug
## 2.0.2(2023-12-05)
-优化 size 属性支持单位
## 2.0.1(2023-12-05)
- 新增 uni-app x 支持定义图标
## 1.3.5(2022-01-24)
- 优化 size 属性可以传入不带单位的字符串数值
## 1.3.4(2022-01-24)
- 优化 size 支持其他单位
## 1.3.3(2022-01-17)
- 修复 nvue 有些图标不显示的bug,兼容老版本图标
## 1.3.2(2021-12-01)
- 优化 示例可复制图标名称
## 1.3.1(2021-11-23)
- 优化 兼容旧组件 type 值
## 1.3.0(2021-11-19)
- 新增 更多图标
- 优化 自定义图标使用方式
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
## 1.1.7(2021-11-08)
## 1.2.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.5(2021-05-12)
- 新增 组件示例地址
## 1.1.4(2021-02-05)
- 调整为uni_modules目录规范
<template>
<text class="uni-icons" :style="styleObj">
<slot>{{unicode}}</slot>
</text>
</template>
<script>
import { fontData, IconsDataItem } from './uniicons_file'
/**
* Icons 图标
* @description 用于展示 icon 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number,String} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: "uni-icons",
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
fontFamily: {
type: String,
default: ''
}
},
data() {
return {};
},
computed: {
unicode() : string {
let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type })
if (codes !== null) {
return codes.unicode
}
return ''
},
iconSize() : string {
const size = this.size
if (typeof size == 'string') {
const reg = /^[0-9]*$/g
return reg.test(size as string) ? '' + size + 'px' : '' + size;
// return '' + this.size
}
return this.getFontSize(size as number)
},
styleObj() : UTSJSONObject {
if (this.fontFamily !== '') {
return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily }
}
return { color: this.color, fontSize: this.iconSize }
}
},
created() { },
methods: {
/**
* 字体大小
*/
getFontSize(size : number) : string {
return size + 'px';
},
},
}
</script>
<style scoped>
@font-face {
font-family: UniIconsFontFamily;
src: url('./uniicons.ttf');
}
.uni-icons {
font-family: UniIconsFontFamily;
font-size: 18px;
font-style: normal;
color: #333;
}
</style>
<template>
<!-- #ifdef APP-NVUE -->
<text :style="styleObj" class="uni-icons" @click="_onClick">{{unicode}}</text>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<text :style="styleObj" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick">
<slot></slot>
</text>
<!-- #endif -->
</template>
<script>
import { fontData } from './uniicons_file_vue.js';
const getVal = (val) => {
const reg = /^[0-9]*$/g
return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val;
}
// #ifdef APP-NVUE
var domModule = weex.requireModule('dom');
import iconUrl from './uniicons.ttf'
domModule.addRule('fontFace', {
'fontFamily': "uniicons",
'src': "url('" + iconUrl + "')"
});
// #endif
/**
* Icons 图标
* @description 用于展示 icons 图标
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
* @property {Number} size 图标大小
* @property {String} type 图标图案,参考示例
* @property {String} color 图标颜色
* @property {String} customPrefix 自定义图标
* @event {Function} click 点击 Icon 触发事件
*/
export default {
name: 'UniIcons',
emits: ['click'],
props: {
type: {
type: String,
default: ''
},
color: {
type: String,
default: '#333333'
},
size: {
type: [Number, String],
default: 16
},
customPrefix: {
type: String,
default: ''
},
fontFamily: {
type: String,
default: ''
}
},
data() {
return {
icons: fontData
}
},
computed: {
unicode() {
let code = this.icons.find(v => v.font_class === this.type)
if (code) {
return code.unicode
}
return ''
},
iconSize() {
return getVal(this.size)
},
styleObj() {
if (this.fontFamily !== '') {
return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`
}
return `color: ${this.color}; font-size: ${this.iconSize};`
}
},
methods: {
_onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss">
/* #ifndef APP-NVUE */
@import './uniicons.css';
@font-face {
font-family: uniicons;
src: url('./uniicons.ttf');
}
/* #endif */
.uni-icons {
font-family: uniicons;
text-decoration: none;
text-align: center;
}
</style>
This diff is collapsed.
{
"id": "uni-icons",
"displayName": "uni-icons 图标",
"version": "2.0.10",
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
"keywords": [
"uni-ui",
"uniui",
"icon",
"图标"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": "^3.2.14"
},
"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"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y",
"app-uvue": "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",
"钉钉": "y",
"快手": "y",
"飞书": "y",
"京东": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}
## Icons 图标
> **组件名:uni-icons**
> 代码块: `uIcons`
用于展示 icons 图标 。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment