wangchen 2023-07-06 17:08:59 +08:00
parent 3967cba687
commit 3a4fd8b906
13 changed files with 1506 additions and 73 deletions

View File

@ -3,7 +3,7 @@
<view class="info">
<image class="toux" src="@/static/images/theme/toux.png" mode="widthFix"></image>
<text>wchenp</text>
<uni-icons type="gear" size="21"/>
<uni-icons type="gear" size="21" @click="uni.navigateBack('-1')"/>
</view>
</view>

View File

@ -0,0 +1,42 @@
<template>
<view class="headInfo">
<uni-icons class="icon" type="back" size="21" @click="toBack" />
{{title}}
<uni-icons type="bottom" size="18" />
</view>
</template>
<script>
export default {
name: "headView",
props: {
title: {
type: String
},
},
methods: {
toBack() {
uni.navigateBack('-1')
}
}
}
</script>
<style>
.headInfo {
position: relative;
background-color: #fff;
height: 40px;
line-height: 40px;
font-size: 18px;
text-align: center;
.icon {
position: absolute;
top: 3px;
left: 10px;
}
}
</style>

View File

@ -18,9 +18,11 @@
<view class="item">
货物质量
</view>
<view class="item">
<navigator url="/pages/monitor/index" open-type="redirect">
<view class="item" :class="path==5?'active':''">
场位监控
</view>
</navigator>
</view>
</template>
<script>

View File

@ -3,7 +3,13 @@
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
"navigationBarTitleText": "装船指令"
}
},
{
"path": "pages/index/instruct",
"style": {
"navigationBarTitleText": "指令"
}
},
{
@ -17,6 +23,12 @@
"style": {
"navigationBarTitleText": "船舶作业"
}
},
{
"path": "pages/monitor/index",
"style": {
"navigationBarTitleText": "场位监控"
}
}
],
"tabBar": {

View File

@ -5,11 +5,17 @@
<side-bar path='1'></side-bar>
<view class="content">
<view class="form">
<input class="input" type="text" placeholder="港区" />
<input class="input" type="text" placeholder="船名/航次" />
<view class="end">
<uni-easyinput class="input" suffixIcon="search" v-model="value1" placeholder="港区"
@iconClick="iconClick">
</uni-easyinput>
<uni-easyinput class="input" suffixIcon="search" v-model="value2" placeholder="船名/航次"
@iconClick="iconClick">
</uni-easyinput>
</view>
</view>
<view class="itemList">
<view v-for="(item, index) in ltemList" :key="index" class="item">
<view v-for="(item, index) in ltemList" :key="index" class="item" @click="toDetails">
<view class="title">
<view class="name">
海王星领袖
@ -19,15 +25,21 @@
<text v-else> </text>
</view>
</view>
<view class="">
<view class="table">
<view class="row">
<text>航次:735546</text>
<text>贸易类型: 内贸</text>
<view class="nitem">
航次: <text>735546</text>
</view>
<view class="nitem">
贸易类型: <text>内贸</text>
</view>
</view>
<view class="row">
<text>进出口: 进口</text>
<text>泊位: 一泊位</text>
<view class="nitem">
进出口: <text>进口</text>
</view>
<view class="nitem">
泊位: <text>一泊位</text>
</view>
</view>
</view>
@ -45,7 +57,9 @@
export default {
data() {
return {
ltemList:[1,1,1,1,2,1,1,1,1],
value1: '',
value2: '',
ltemList: [1, 1, 1, 1, 2, 1, 1, 1, 1],
}
},
onLoad() {
@ -56,7 +70,11 @@
HeadInfo
},
methods: {
toDetails() {
uni.navigateTo({
url: '/pages/index/instruct'
})
}
}
};
</script>
@ -74,22 +92,28 @@
display: flex;
justify-content: flex-end;
.end {
width: 500px;
display: flex;
justify-content: space-between;
.input {
width: 200px;
height: 35px;
line-height: 35px;
border: 1px solid #c9cacb;
border-radius: 5px;
padding-left: 10px;
margin-left: 15px;
}
}
}
.itemList {
width: 100%;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
.item {
width: 32%;
margin-top: 15px;
@ -97,6 +121,7 @@
height: 160px;
border: 1px solid #c9cacb;
padding: 22px 15px;
.title {
display: flex;
justify-content: space-between;
@ -104,20 +129,30 @@
margin-bottom: 20px;
font-weight: 700;
}
.status {
font-size: 16px;
font-weight: 400;
}
.row {
display: flex;
justify-content: space-between;
font-size: 18px;
margin: 10px 0;
.text {
display: block;
.nitem {
width: 46%;
text {
color: #929292;
}
}
}
}
.item:nth-child(3n) {
margin-right: 0;
}

View File

@ -0,0 +1,174 @@
<template>
<view class="app">
<head-view title="船名/航次"></head-view>
<view class="content">
<view class="form">
<view class="input">
<uni-easyinput class="input" suffixIcon="search" v-model="value1" placeholder="船名/航次"
@iconClick="iconClick">
</uni-easyinput>
</view>
<view class="select">
<uni-data-select v-model="value" :localdata="range" @change="change" placeholder="港区">
</uni-data-select>
</view>
<view class="select">
<uni-data-select v-model="value" :localdata="range" @change="change" placeholder="贸易类型">
</uni-data-select>
</view>
<view class="select">
<uni-data-select v-model="value" :localdata="range" @change="change" placeholder="品牌">
</uni-data-select>
</view>
<view class="select">
<uni-data-select v-model="value" :localdata="range" @change="change" placeholder="车型">
</uni-data-select>
</view>
<view class="select">
<uni-data-select v-model="value" :localdata="range" @change="change" placeholder="港口">
</uni-data-select>
</view>
<view class="select">
<uni-data-select v-model="value" :localdata="range" @change="change" placeholder="计划状态">
</uni-data-select>
</view>
</view>
<view class="uni-list">
<radio-group class="group" @change="radioChange">
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in items" :key="item.value">
<view>
<radio :value="item.value" :checked="index === current" />{{item.name}}
</view>
</label>
</radio-group>
</view>
<view class="buttonlist">
<button class="button" type="default">指令发送</button>
<button class="button" type="default">装船要求</button>
<button class="button" type="default">刷新</button>
</view>
<view class="tablist">
<view class="tab" :class="active==1?'active':''" type="default" @click="active=1"></view>
<view class="tab" :class="active==2?'active':''" type="default" @click="active=2"></view>
</view>
</view>
</view>
</template>
<script>
import HeadView from '@/components/head-view/head-view.vue';
export default {
data() {
return {
value1: "",
value: '',
ltemList: [1, 1, 1, 1, 2, 1, 1, 1, 1],
range: [1],
items: [{
value: '1',
name: '总指令',
checked: 'true'
},
{
value: '2',
name: '分指令'
},
{
value: '3',
name: '配载图'
},
{
value: '4',
name: '场位图'
},
],
current: 0,
active: 1
}
},
onLoad() {
},
components: {
HeadView
},
methods: {
change() {},
radioChange: function(evt) {
for (let i = 0; i < this.items.length; i++) {
if (this.items[i].value === evt.detail.value) {
this.current = i;
break;
}
}
}
}
};
</script>
<style>
.content {
padding: 20px;
.form {
display: flex;
.select {
width: 100px;
margin-left: 15px;
}
.input {
width: 200px;
height: 35px;
line-height: 35px;
}
}
.uni-list {
margin-top: 20px;
.group {
width: 360px;
height: 50px;
display: flex;
justify-content: space-between;
}
}
.buttonlist {
width: 340px;
display: flex;
justify-content: space-between;
.button {
width: 100px;
height: 40px;
line-height: 40px;
}
}
.tablist {
width: 175px;
height: 60px;
line-height: 60px;
font-size: 21px;
display: flex;
justify-content: space-between;
.tabs {
width: 80px;
height: 60px;
border-bottom: 2rpx solid #ebebeb;
}
.active {
color: #1890ff;
border-bottom: 2rpx solid #1890ff;
}
}
}
</style>

View File

@ -0,0 +1,204 @@
<template>
<view class="app">
<head-info></head-info>
<view class="container">
<side-bar path='5'></side-bar>
<view class="content">
<view class="form">
<button type="primary" class="button">
<uni-icons type="plusempty" color="#fff" size="20"></uni-icons>
</button>
<view class="right">
<uni-easyinput suffixIcon="search" v-model="value" placeholder="船名/航次" @iconClick="iconClick">
</uni-easyinput>
<view class="select">
<uni-data-select v-model="value1" :localdata="range1" @change="change">
</uni-data-select>
</view>
<view class="select">
<uni-data-select v-model="value2" :localdata="range2" @change="change">
</uni-data-select>
</view>
<view class="select">
<uni-data-select v-model="value3" :localdata="range3" @change="change">
</uni-data-select>
</view>
</view>
</view>
<view class="itemList">
<view class="item" v-for="item in itemList" :key="item.index">
<view class="row">
<view class="col weight">
CJH290387532753799
</view>
<view class="col">
品牌特斯拉
</view>
<view class="col">
车型轿车
</view>
</view>
<view class="row">
<view class="col">
船名运程10
</view>
<view class="col">
航次HC867468096
</view>
<view class="col">
场位A2-09-08
</view>
</view>
<view class="row">
<view class="col">
货物状态已装船
</view>
<view class="col">
作业时间2023/09/08 14:00
</view>
<view class="col">
作业人张星星
</view>
</view>
<view class="row">
<view class="col">
质损发生环节收车交接
</view>
<view class="col">
质损概况碰撞
</view>
<view class="col">
处置情况带伤发运
</view>
</view>
<view class="rowFoot">
<view class="col">
详情
</view>
<view class="col">
编辑
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import SideBar from '@/components/sider-bar/slider-bar';
import HeadInfo from '@/components/head-info/head-info';
export default {
data() {
return {
value:'',
value1:'',
value2:'',
value3:'',
range1: [{
value: 0,
text: "一号港"
},
],
range2: [{
value: 0,
text: "一号港"
},
],
range3: [{
value: 0,
text: "一号港"
},
],
itemList: [1, 1, 1, 1, 2, 1, 1, 1, 1],
}
},
onLoad() {
},
components: {
SideBar,
HeadInfo
},
methods: {
iconClick(type) {
uni.showToast({
title: `点击了${type==='prefix'?'左侧':'右侧'}的图标`,
icon: 'none'
})
},
change(e) {
console.log(e);
}
}
};
</script>
<style>
.container {
display: flex;
}
.content {
flex: 1;
padding: 20px;
.form {
display: flex;
justify-content: space-between;
height: 40px;
line-height: 40px;
.button {
width: 90px;
height: 40px;
line-height: 40px;
text-align: center;
margin: 0;
}
.right {
width: 600px;
height: 40px;
display: flex;
justify-content: space-between;
.select {
width: 130px;
margin-left: 20px;
.uni-select {
height: 40px;
}
}
}
}
.itemList {
margin-top: 30px;
.item {
height: 110px;
padding: 20px;
border-bottom: 2px solid #e9e9e9;
display: flex;
justify-content: space-between;
.weight {
font-weight: 900;
}
.row {
width: 22%;
flex-direction: column;
display: flex;
justify-content: space-between;
}
.rowFoot {
width: 12%;
flex-direction: column;
display: flex;
justify-content: space-around;
color: #1890ff;
}
}
}
}
</style>

View File

@ -9,7 +9,11 @@
<uni-data-select v-model="value" :localdata="range" @change="change">
</uni-data-select>
</view>
<input class="input" type="text" placeholder="船名/航次" />
<view class="input">
<uni-easyinput class="input" suffixIcon="search" v-model="value1" placeholder="船名/航次"
@iconClick="iconClick">
</uni-easyinput>
</view>
</view>
<view class="itemList">
<view v-for="(item, index) in ltemList" :key="index" class="item">
@ -17,22 +21,58 @@
<view class="name">
海王星领袖
</view>
<view class="status">
<text v-if="item==1" class="green"> </text>
<text v-else> </text>
</view>
</view>
<view class="">
<view class="table">
<view class="row">
<text>航次:735546</text>
<text>贸易类型: 内贸</text>
<view class="nitem">
进口航次: <text>735546</text>
</view>
<view class="nitem">
贸易类型: <text>内贸</text>
</view>
</view>
<view class="row">
<text>进出口: 进口</text>
<text>泊位: 一泊位</text>
<view class="nitem">
出口航次: <text>555546</text>
</view>
<view class="nitem">
贸易类型: <text>外贸</text>
</view>
</view>
<view class="row">
<view class="nitem">
计划泊位: <text>一泊位</text>
</view>
<view class="nitem">
实际泊位: <text>一泊位</text>
</view>
</view>
<view class="row">
<view class="nitem" v-if="item==1">
<text class="green"></text> 已下载
<text>2023/09/21 12:00</text>
</view>
<view class="nitem" v-if="item==2">
<text></text> 未下载
</view>
<view class="nitem" v-if="item==1">
<text class="green"></text> 已上传
<text>2023/09/21 12:00</text>
</view>
<view class="nitem" v-if="item==2">
<text></text> 未上传
</view>
</view>
<view class="footer">
<view class="fitem">
下载
</view>
<view class="fitem">
上传
</view>
</view>
</view>
</view>
</view>
@ -49,20 +89,21 @@
data() {
return {
value: 0,
value1:'',
range: [{
value: 0,
text: "篮球"
text: "一号港"
},
{
value: 1,
text: "足球"
text: "二号港"
},
{
value: 2,
text: "游泳"
text: "不冻港"
},
],
ltemList: [1, 1, 1, 1, 2, 1, 1, 1, 1],
ltemList: [1, 2, 1, 1, 2, 1, 1, 1, 1],
}
},
onLoad() {
@ -88,18 +129,18 @@
.content {
padding: 20px;
.form {
display: flex;
.select {
width: 100px;
}
.input {
width: 200px;
height: 35px;
line-height: 35px;
border: 1px solid #c9cacb;
border-radius: 5px;
padding-left: 10px;
margin-left: 15px;
}
}
@ -109,39 +150,54 @@
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
.item {
width: 48%;
width: 49%;
margin-top: 15px;
margin-right: 4%;
height: 160px;
margin-right: 2%;
border: 1px solid #c9cacb;
padding: 22px 15px;
.title {
display: flex;
justify-content: space-between;
font-size: 21px;
margin-bottom: 20px;
padding: 10px 20px;
font-weight: 700;
}
.status {
font-size: 16px;
font-weight: 400;
}
.row {
display: flex;
justify-content: space-between;
font-size: 18px;
margin: 10px 0;
padding: 10px 20px;
.nitem {
width: 46%;
.text {
display: block;
color: #929292;
}
}
}
.footer {
display: flex;
justify-content: space-between;
height: 60px;
line-height: 60px;
font-size: 21px;
background-color: #f7f9fa;
color: #8d8f8f;
.fitem {
width: 50%;
text-align: center;
}
}
}
.item:nth-child(2n) {
margin-right: 0;
}

View File

@ -0,0 +1,97 @@
## 1.1.92023-04-11
- 修复 vue3 下 keyboardheightchange 事件报错的bug
## 1.1.82023-03-29
- 优化 trim 属性默认值
## 1.1.72023-03-29
- 新增 cursor-spacing 属性
## 1.1.62023-01-28
- 新增 keyboardheightchange 事件,可监听键盘高度变化
## 1.1.52022-11-29
- 优化 主题样式
## 1.1.42022-10-27
- 修复 props 中背景颜色无默认值的bug
## 1.1.02022-06-30
- 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容
- 新增 clear 事件,点击右侧叉号图标触发
- 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发
- 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等
## 1.0.52022-06-07
- 优化 clearable 显示策略
## 1.0.42022-06-07
- 优化 clearable 显示策略
## 1.0.32022-05-20
- 修复 关闭图标某些情况下无法取消的 bug
## 1.0.22022-04-12
- 修复 默认值不生效的 bug
## 1.0.12022-04-02
- 修复 value 不能为 0 的 bug
## 1.0.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-easyinput](https://uniapp.dcloud.io/component/uniui/uni-easyinput)
## 0.1.42021-08-20
- 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
## 0.1.32021-08-11
- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题
## 0.1.22021-07-30
- 优化 vue3 下事件警告的问题
## 0.1.1
- 优化 errorMessage 属性支持 Boolean 类型
## 0.1.02021-07-13
- 组件兼容 vue3如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 0.0.162021-06-29
- 修复 confirmType 属性(仅 type="text" 生效)导致多行文本框无法换行的 bug
## 0.0.152021-06-21
- 修复 passwordIcon 属性拼写错误的 bug
## 0.0.142021-06-18
- 新增 passwordIcon 属性,当 type=password 时是否显示小眼睛图标
- 修复 confirmType 属性不生效的问题
## 0.0.132021-06-04
- 修复 disabled 状态可清出内容的 bug
## 0.0.122021-05-12
- 新增 组件示例地址
## 0.0.112021-05-07
- 修复 input-border 属性不生效的问题
## 0.0.102021-04-30
- 修复 ios 遮挡文字、显示一半的问题
## 0.0.92021-02-05
- 调整为 uni_modules 目录规范
- 优化 兼容 nvue 页面

View File

@ -0,0 +1,56 @@
/**
* @desc 函数防抖
* @param func 目标函数
* @param wait 延迟执行毫秒数
* @param immediate true - 立即执行 false - 延迟执行
*/
export const debounce = function(func, wait = 1000, immediate = true) {
let timer;
console.log(1);
return function() {
console.log(123);
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)
}
}
}
}

View File

@ -0,0 +1,657 @@
<template>
<view class="uni-easyinput" :class="{ 'uni-easyinput-error': msg }" :style="boxStyle">
<view class="uni-easyinput__content" :class="inputContentClass" :style="inputContentStyle">
<uni-icons v-if="prefixIcon" class="content-clear-icon" :type="prefixIcon" color="#c0c4cc" @click="onClickIcon('prefix')" size="22"></uni-icons>
<textarea
v-if="type === 'textarea'"
class="uni-easyinput__content-textarea"
:class="{ 'input-padding': inputBorder }"
:name="name"
:value="val"
:placeholder="placeholder"
:placeholderStyle="placeholderStyle"
:disabled="disabled"
placeholder-class="uni-easyinput__placeholder-class"
:maxlength="inputMaxlength"
:focus="focused"
:autoHeight="autoHeight"
:cursor-spacing="cursorSpacing"
@input="onInput"
@blur="_Blur"
@focus="_Focus"
@confirm="onConfirm"
@keyboardheightchange="onkeyboardheightchange"
></textarea>
<input
v-else
:type="type === 'password' ? 'text' : type"
class="uni-easyinput__content-input"
:style="inputStyle"
:name="name"
:value="val"
:password="!showPassword && type === 'password'"
:placeholder="placeholder"
:placeholderStyle="placeholderStyle"
placeholder-class="uni-easyinput__placeholder-class"
:disabled="disabled"
:maxlength="inputMaxlength"
:focus="focused"
:confirmType="confirmType"
:cursor-spacing="cursorSpacing"
@focus="_Focus"
@blur="_Blur"
@input="onInput"
@confirm="onConfirm"
@keyboardheightchange="onkeyboardheightchange"
/>
<template v-if="type === 'password' && passwordIcon">
<!-- 开启密码时显示小眼睛 -->
<uni-icons
v-if="isVal"
class="content-clear-icon"
:class="{ 'is-textarea-icon': type === 'textarea' }"
:type="showPassword ? 'eye-slash-filled' : 'eye-filled'"
:size="22"
:color="focusShow ? primaryColor : '#c0c4cc'"
@click="onEyes"
></uni-icons>
</template>
<template v-else-if="suffixIcon">
<uni-icons v-if="suffixIcon" class="content-clear-icon" :type="suffixIcon" color="#c0c4cc" @click="onClickIcon('suffix')" size="22"></uni-icons>
</template>
<template v-else>
<uni-icons
v-if="clearable && isVal && !disabled && type !== 'textarea'"
class="content-clear-icon"
:class="{ 'is-textarea-icon': type === 'textarea' }"
type="clear"
:size="clearSize"
:color="msg ? '#dd524d' : focusShow ? primaryColor : '#c0c4cc'"
@click="onClear"
></uni-icons>
</template>
<slot name="right"></slot>
</view>
</view>
</template>
<script>
/**
* Easyinput 输入框
* @description 此组件可以实现表单的输入与校验包括 "text" "textarea" 类型
* @tutorial https://ext.dcloud.net.cn/plugin?id=3455
* @property {String} value 输入内容
* @property {String } type 输入框的类型默认text password/text/textarea/..
* @value text 文本输入键盘
* @value textarea 多行文本输入键盘
* @value password 密码输入键盘
* @value number 数字输入键盘注意iOS上app-vue弹出的数字键盘并非9宫格方式
* @value idcard 身份证输入键盘支付宝百度QQ小程序
* @value digit 带小数点的数字键盘 App的nvue页面微信支付宝百度头条QQ小程序支持
* @property {Boolean} clearable 是否显示右侧清空内容的图标控件点击可清空输入框内容默认true
* @property {Boolean} autoHeight 是否自动增高输入区域type为textarea时有效默认true
* @property {String } placeholder 输入框的提示文字
* @property {String } placeholderStyle placeholder的样式(内联样式字符串)"color: #ddd"
* @property {Boolean} focus 是否自动获得焦点默认false
* @property {Boolean} disabled 是否禁用默认false
* @property {Number } maxlength 最大输入长度设置为 -1 的时候不限制最大长度默认140
* @property {String } confirmType 设置键盘右下角按钮的文字仅在type="text"时生效默认done
* @property {Number } clearSize 清除图标的大小单位px默认15
* @property {String} prefixIcon 输入框头部图标
* @property {String} suffixIcon 输入框尾部图标
* @property {String} primaryColor 设置主题色默认#2979ff
* @property {Boolean} trim 是否自动去除两端的空格
* @property {Boolean} cursorSpacing 指定光标与键盘的距离单位 px
* @value both 去除两端空格
* @value left 去除左侧空格
* @value right 去除右侧空格
* @value start 去除左侧空格
* @value end 去除右侧空格
* @value all 去除全部空格
* @value none 不去除空格
* @property {Boolean} inputBorder 是否显示input输入框的边框默认true
* @property {Boolean} passwordIcon type=password时是否显示小眼睛图标
* @property {Object} styles 自定义颜色
* @event {Function} input 输入框内容发生变化时触发
* @event {Function} focus 输入框获得焦点时触发
* @event {Function} blur 输入框失去焦点时触发
* @event {Function} confirm 点击完成按钮时触发
* @event {Function} iconClick 点击图标时触发
* @example <uni-easyinput v-model="mobile"></uni-easyinput>
*/
function obj2strClass(obj) {
let classess = '';
for (let key in obj) {
const val = obj[key];
if (val) {
classess += `${key} `;
}
}
return classess;
}
function obj2strStyle(obj) {
let style = '';
for (let key in obj) {
const val = obj[key];
style += `${key}:${val};`;
}
return style;
}
export default {
name: 'uni-easyinput',
emits: ['click', 'iconClick', 'update:modelValue', 'input', 'focus', 'blur', 'confirm', 'clear', 'eyes', 'change', 'keyboardheightchange'],
model: {
prop: 'modelValue',
event: 'update:modelValue'
},
options: {
virtualHost: true
},
inject: {
form: {
from: 'uniForm',
default: null
},
formItem: {
from: 'uniFormItem',
default: null
}
},
props: {
name: String,
value: [Number, String],
modelValue: [Number, String],
type: {
type: String,
default: 'text'
},
clearable: {
type: Boolean,
default: true
},
autoHeight: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: ' '
},
placeholderStyle: String,
focus: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
maxlength: {
type: [Number, String],
default: 140
},
confirmType: {
type: String,
default: 'done'
},
clearSize: {
type: [Number, String],
default: 24
},
inputBorder: {
type: Boolean,
default: true
},
prefixIcon: {
type: String,
default: ''
},
suffixIcon: {
type: String,
default: ''
},
trim: {
type: [Boolean, String],
default: false
},
cursorSpacing: {
type: Number,
default: 0
},
passwordIcon: {
type: Boolean,
default: true
},
primaryColor: {
type: String,
default: '#2979ff'
},
styles: {
type: Object,
default() {
return {
color: '#333',
backgroundColor: '#fff',
disableColor: '#F7F6F6',
borderColor: '#e5e5e5'
};
}
},
errorMessage: {
type: [String, Boolean],
default: ''
}
},
data() {
return {
focused: false,
val: '',
showMsg: '',
border: false,
isFirstBorder: false,
showClearIcon: false,
showPassword: false,
focusShow: false,
localMsg: '',
isEnter: false // 使
};
},
computed: {
//
isVal() {
const val = this.val;
// fixed by mehaotian 00
if (val || val === 0) {
return true;
}
return false;
},
msg() {
// console.log('computed', this.form, this.formItem);
// if (this.form) {
// return this.errorMessage || this.formItem.errMsg;
// }
// TODO formItem errMsg
return this.localMsg || this.errorMessage;
},
// uniappinputmaxlength
inputMaxlength() {
return Number(this.maxlength);
},
// style
boxStyle() {
return `color:${this.inputBorder && this.msg ? '#e43d33' : this.styles.color};`;
},
// input
inputContentClass() {
return obj2strClass({
'is-input-border': this.inputBorder,
'is-input-error-border': this.inputBorder && this.msg,
'is-textarea': this.type === 'textarea',
'is-disabled': this.disabled,
'is-focused': this.focusShow
});
},
inputContentStyle() {
const focusColor = this.focusShow ? this.primaryColor : this.styles.borderColor;
const borderColor = this.inputBorder && this.msg ? '#dd524d' : focusColor;
return obj2strStyle({
'border-color': borderColor || '#e5e5e5',
'background-color': this.disabled ? this.styles.disableColor : this.styles.backgroundColor
});
},
// input
inputStyle() {
const paddingRight = this.type === 'password' || this.clearable || this.prefixIcon ? '' : '10px';
return obj2strStyle({
'padding-right': paddingRight,
'padding-left': this.prefixIcon ? '' : '10px'
});
}
},
watch: {
value(newVal) {
this.val = newVal;
},
modelValue(newVal) {
this.val = newVal;
},
focus(newVal) {
this.$nextTick(() => {
this.focused = this.focus;
this.focusShow = this.focus;
});
}
},
created() {
this.init();
// TODO vue3 computed inject formItem.errMsg
if (this.form && this.formItem) {
this.$watch('formItem.errMsg', newVal => {
this.localMsg = newVal;
});
}
},
mounted() {
this.$nextTick(() => {
this.focused = this.focus;
this.focusShow = this.focus;
});
},
methods: {
/**
* 初始化变量值
*/
init() {
if (this.value || this.value === 0) {
this.val = this.value;
} else if (this.modelValue || this.modelValue === 0 || this.modelValue === '') {
this.val = this.modelValue;
} else {
this.val = null;
}
},
/**
* 点击图标时触发
* @param {Object} type
*/
onClickIcon(type) {
this.$emit('iconClick', type);
},
/**
* 显示隐藏内容密码框时生效
*/
onEyes() {
this.showPassword = !this.showPassword;
this.$emit('eyes', this.showPassword);
},
/**
* 输入时触发
* @param {Object} event
*/
onInput(event) {
let value = event.detail.value;
//
if (this.trim) {
if (typeof this.trim === 'boolean' && this.trim) {
value = this.trimStr(value);
}
if (typeof this.trim === 'string') {
value = this.trimStr(value, this.trim);
}
}
if (this.errMsg) this.errMsg = '';
this.val = value;
// TODO vue2
this.$emit('input', value);
// TODO  vue3
this.$emit('update:modelValue', value);
},
/**
* 外部调用方法
* 获取焦点时触发
* @param {Object} event
*/
onFocus() {
this.$nextTick(() => {
this.focused = true;
});
this.$emit('focus', null);
},
_Focus(event) {
this.focusShow = true;
this.$emit('focus', event);
},
/**
* 外部调用方法
* 失去焦点时触发
* @param {Object} event
*/
onBlur() {
this.focused = false;
this.$emit('focus', null);
},
_Blur(event) {
let value = event.detail.value;
this.focusShow = false;
this.$emit('blur', event);
// eventstring
if (this.isEnter === false) {
this.$emit('change', this.val);
}
//
if (this.form && this.formItem) {
const { validateTrigger } = this.form;
if (validateTrigger === 'blur') {
this.formItem.onFieldChange();
}
}
},
/**
* 按下键盘的发送键
* @param {Object} e
*/
onConfirm(e) {
this.$emit('confirm', this.val);
this.isEnter = true;
this.$emit('change', this.val);
this.$nextTick(() => {
this.isEnter = false;
});
},
/**
* 清理内容
* @param {Object} event
*/
onClear(event) {
this.val = '';
// TODO vue2
this.$emit('input', '');
// TODO vue2
// TODO  vue3
this.$emit('update:modelValue', '');
//
this.$emit('clear');
},
/**
* 键盘高度发生变化的时候触发此事件
* 兼容性微信小程序2.7.0+App 3.1.0+
* @param {Object} event
*/
onkeyboardheightchange(event) {
this.$emit("keyboardheightchange",event);
},
/**
* 去除空格
*/
trimStr(str, pos = 'both') {
if (pos === 'both') {
return str.trim();
} else if (pos === 'left') {
return str.trimLeft();
} else if (pos === 'right') {
return str.trimRight();
} else if (pos === 'start') {
return str.trimStart();
} else if (pos === 'end') {
return str.trimEnd();
} else if (pos === 'all') {
return str.replace(/\s+/g, '');
} else if (pos === 'none') {
return str;
}
return str;
}
}
};
</script>
<style lang="scss">
$uni-error: #e43d33;
$uni-border-1: #dcdfe6 !default;
.uni-easyinput {
/* #ifndef APP-NVUE */
width: 100%;
/* #endif */
flex: 1;
position: relative;
text-align: left;
color: #333;
font-size: 14px;
}
.uni-easyinput__content {
flex: 1;
/* #ifndef APP-NVUE */
width: 100%;
display: flex;
box-sizing: border-box;
// min-height: 36px;
/* #endif */
flex-direction: row;
align-items: center;
// border
border-color: #fff;
transition-property: border-color;
transition-duration: 0.3s;
}
.uni-easyinput__content-input {
/* #ifndef APP-NVUE */
width: auto;
/* #endif */
position: relative;
overflow: hidden;
flex: 1;
line-height: 1;
font-size: 14px;
height: 35px;
// min-height: 36px;
}
.uni-easyinput__placeholder-class {
color: #999;
font-size: 12px;
// font-weight: 200;
}
.is-textarea {
align-items: flex-start;
}
.is-textarea-icon {
margin-top: 5px;
}
.uni-easyinput__content-textarea {
position: relative;
overflow: hidden;
flex: 1;
line-height: 1.5;
font-size: 14px;
margin: 6px;
margin-left: 0;
height: 80px;
min-height: 80px;
/* #ifndef APP-NVUE */
min-height: 80px;
width: auto;
/* #endif */
}
.input-padding {
padding-left: 10px;
}
.content-clear-icon {
padding: 0 5px;
}
.label-icon {
margin-right: 5px;
margin-top: -1px;
}
//
.is-input-border {
/* #ifndef APP-NVUE */
display: flex;
box-sizing: border-box;
/* #endif */
flex-direction: row;
align-items: center;
border: 1px solid $uni-border-1;
border-radius: 4px;
/* #ifdef MP-ALIPAY */
overflow: hidden;
/* #endif */
}
.uni-error-message {
position: absolute;
bottom: -17px;
left: 0;
line-height: 12px;
color: $uni-error;
font-size: 12px;
text-align: left;
}
.uni-error-msg--boeder {
position: relative;
bottom: 0;
line-height: 22px;
}
.is-input-error-border {
border-color: $uni-error;
.uni-easyinput__placeholder-class {
color: mix(#fff, $uni-error, 50%);
}
}
.uni-easyinput--border {
margin-bottom: 0;
padding: 10px 15px;
// padding-bottom: 0;
border-top: 1px #eee solid;
}
.uni-easyinput-error {
padding-bottom: 0;
}
.is-first-border {
/* #ifndef APP-NVUE */
border: none;
/* #endif */
/* #ifdef APP-NVUE */
border-width: 0;
/* #endif */
}
.is-disabled {
background-color: #f7f6f6;
color: #d5d5d5;
.uni-easyinput__placeholder-class {
color: #d5d5d5;
font-size: 12px;
}
}
</style>

View File

@ -0,0 +1,87 @@
{
"id": "uni-easyinput",
"displayName": "uni-easyinput 增强输入框",
"version": "1.1.9",
"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"
},
"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"
}
}
}
}
}

View File

@ -0,0 +1,11 @@
### 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