11
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 804 B |
Binary file not shown.
|
Before Width: | Height: | Size: 761 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,154 +0,0 @@
|
||||
//搜索
|
||||
<template lang='pug'>
|
||||
view.item-out-view
|
||||
view.search-view
|
||||
view.search-item
|
||||
image(src='../../static/img/search.svg')
|
||||
input(
|
||||
v-model="inputValue"
|
||||
@input='onInputListen'
|
||||
:placeholder='placeholder'
|
||||
:placeholder-class='placeholderClass')
|
||||
|
||||
view.search-content(
|
||||
v-if="historyDatas&&historyDatas.length>0&&inputValue.length<=0")
|
||||
view.title-view
|
||||
text 搜索历史
|
||||
image(src='./icon_delete.png' @tap.stop='onDelete(ALL)')
|
||||
view.item-view(v-for="(item,index) in historyDatas" :key="index" @tap.stop='onItemClick(item,index)')
|
||||
text {{item.key}}
|
||||
image(src='./icon_close.png' @tap.stop='onDelete(index)')
|
||||
view.search-content(v-if="keyworkDatas&&keyworkDatas.length>0")
|
||||
view.item-view(v-for="(item,index) in keyworkDatas" :key="index" @tap.stop='onItemClick(item,index)')
|
||||
text(v-for="textContent in item.keyword"
|
||||
:key="item.id"
|
||||
:class="textContent===inputValue?'__vital':''") {{textContent}}
|
||||
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
inputValue: '',
|
||||
ALL: 'ALL',
|
||||
SEARCH_DATA: 'SEARCH_DATA'
|
||||
}
|
||||
},
|
||||
props: {
|
||||
//搜索历史内容
|
||||
historyDatas: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
//搜索关键内容
|
||||
keyworkDatas: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请输入搜索内容'
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
//监听输入框内容变化
|
||||
onInputListen(event) {
|
||||
let detail = event.detail;
|
||||
let value = detail.value;
|
||||
this.inputValue = value;
|
||||
this.$emit('onInputListen', value);
|
||||
},
|
||||
//清除搜索历史
|
||||
onDelete(event) {
|
||||
this.$emit('onDelete', event);
|
||||
},
|
||||
//列表点击事件
|
||||
onItemClick(item, index) {
|
||||
this.$emit('onItemClick', {
|
||||
item,
|
||||
index
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style scoped lang='scss'>
|
||||
.item-out-view {
|
||||
flex-direction: column;
|
||||
.search-view {
|
||||
border-bottom: 1rpx solid #dddddd;
|
||||
flex-direction: column;
|
||||
padding: 10rpx 32rpx;
|
||||
background: rgba(255, 255, 255, 1);
|
||||
.search-item {
|
||||
width: 80%;
|
||||
padding: 0 24rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
background: rgba(249, 249, 249, 1);
|
||||
border-radius: 200px;
|
||||
align-items: center;
|
||||
input {
|
||||
padding: 0 24rpx;
|
||||
height: 80rpx;
|
||||
font-weight: 400;
|
||||
flex: 1;
|
||||
text-align: start;
|
||||
font-size: 28rpx;
|
||||
font-family: PingFang-SC-Bold, PingFang-SC;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
}
|
||||
.placeholderClass {
|
||||
color: #CCCCCC;
|
||||
}
|
||||
image {
|
||||
height: 32rpx;
|
||||
width: 32rpx;
|
||||
}
|
||||
}
|
||||
.search-content {
|
||||
padding: 40rpx 0;
|
||||
flex-direction: column;
|
||||
.title-view {
|
||||
text {
|
||||
color: rgba(51, 51, 51, 1);
|
||||
}
|
||||
}
|
||||
.item-view {
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 32rpx 0;
|
||||
border-bottom: 1px solid rgba(245, 245, 245, 1);
|
||||
text {
|
||||
color: rgba(102, 102, 102, 1);
|
||||
}
|
||||
.next-ico {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
}
|
||||
.__vital {
|
||||
color: rgba(51, 130, 255, 1);
|
||||
}
|
||||
}
|
||||
image {
|
||||
margin-left: auto;
|
||||
width: 44rpx;
|
||||
height: 44rpx;
|
||||
}
|
||||
}
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
font-family: PingFangSC-Regular, PingFang SC;
|
||||
font-weight: 400;
|
||||
}
|
||||
view {
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 858 B |
@@ -1,208 +0,0 @@
|
||||
<template>
|
||||
<view class="body" @click="goInfo(companyitem.missionNo)">
|
||||
<view class="heads">
|
||||
<view class="head_left">
|
||||
<rich-text :nodes="string">
|
||||
</rich-text>
|
||||
</view>
|
||||
|
||||
<view class="head_right">
|
||||
{{companyitem.wage}}{{wageUnit[companyitem.wageUnitCategory]}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="ask">
|
||||
<view class="askList" v-for="(item,index) in skillNames" :key="index">
|
||||
{{item}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="allName">
|
||||
{{companyitem.companyName}}
|
||||
</view>
|
||||
<view class="timeAddress">
|
||||
<view>
|
||||
报名截止日期:{{dateFormat(companyitem.etimePub)}}
|
||||
</view>
|
||||
<view v-if="near">
|
||||
{{companyitem.distanceStr}}km
|
||||
</view>
|
||||
<view v-else>
|
||||
{{getCity(companyitem.cityId)}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="comment" v-if='comment' @tap.stop="goComment(companyitem.missionNo)">
|
||||
<view class="comment_content commentimg" v-if='companyitem.scoreAll>0'>
|
||||
<image class="commentimg_image" src="../../static/img/star.full.svg" v-for="index1 in companyitem.scoreAll" mode=""
|
||||
:key="index1"></image>
|
||||
<image class="commentimg_image" src="../../static/img/star.empty.svg" v-for="index2 in (5-companyitem.scoreAll)"
|
||||
mode="" :key="index2"></image>
|
||||
</view>
|
||||
<view class="comment_content allName gocomment" v-else>
|
||||
评价
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
toDoller,
|
||||
dateFormat
|
||||
} from "../../untils/format.js";
|
||||
import dictionary from '@/common/textdata.js';
|
||||
|
||||
export default {
|
||||
beforeCreate: function() {},
|
||||
props: {
|
||||
companyitem: {
|
||||
type: Object,
|
||||
default(){ return [] }
|
||||
},
|
||||
comment: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
noApply: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
near: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
...dictionary,
|
||||
string: "<div style='overflow: hidden;white-space: nowrap;text-overflow: ellipsis;'>" + this.companyitem.missionTitle +
|
||||
"</div>"
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
skillNames() {
|
||||
return this.companyitem.skillNames.split(',')
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goComment: function(no) {
|
||||
uni.navigateTo({
|
||||
url: `../../pageMy/mycomment/mycomment?missionNo=${encodeURIComponent(no)}`
|
||||
})
|
||||
},
|
||||
goInfo: function(no) {
|
||||
const isCan = this.noApply === false ? '0' : '1'
|
||||
uni.navigateTo({
|
||||
url: `/pages/projectInfo/projectInfo?missionNo=${encodeURIComponent(no)}&isCan=${isCan}`
|
||||
})
|
||||
},
|
||||
getCity: function(val) {
|
||||
if (val) {
|
||||
let areas = this.$store.getters.getAreaParents(val)
|
||||
if (areas.length === 3) {
|
||||
return areas[0].label + '-' + areas[1].label + '-' + areas[2].label
|
||||
}
|
||||
}
|
||||
},
|
||||
toDoller,
|
||||
dateFormat
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.commentimg_image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
|
||||
.commentimg {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.gocomment {
|
||||
font-size: 26rpx !important;
|
||||
border-radius: 5rpx;
|
||||
border: 1rpx solid #c3c3c3;
|
||||
width: 160rpx;
|
||||
text-align: center;
|
||||
float: right;
|
||||
height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
}
|
||||
|
||||
.timeAddress {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
margin: 10rpx 0;
|
||||
}
|
||||
|
||||
.allName {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.askList {
|
||||
width: 14%;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
background-color: #f6f6f6;
|
||||
padding: 5rpx 15rpx;
|
||||
margin-right: 10rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.ask {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.head_right {
|
||||
ont-family: PingFangSC-Medium;
|
||||
font-size: 28rpx;
|
||||
color: #F46161;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.head_left {
|
||||
font-family: PingFangSC-Medium;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
width: 400rpx;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
/*不换行*/
|
||||
text-overflow: ellipsis;
|
||||
/*超出部分文字以...显示*/
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: #F46161;
|
||||
}
|
||||
|
||||
.body {
|
||||
width: 690rpx;
|
||||
margin: 0rpx auto;
|
||||
padding: 20rpx 0;
|
||||
background-color: #fefefe;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.heads {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
@@ -1,30 +0,0 @@
|
||||
<template>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button type="default" open-type="contact">
|
||||
<image src="../../static/img/cs.svg" class="cs" mode=""></image>
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 || APP-PLUS -->
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.csimage {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
position: fixed;
|
||||
right: 22rpx;
|
||||
bottom: 112rpx;
|
||||
}
|
||||
|
||||
.cs {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
position: fixed;
|
||||
right: 22rpx;
|
||||
bottom: 22rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -1,83 +0,0 @@
|
||||
<template>
|
||||
<view :class="className" @click="click">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String
|
||||
},
|
||||
inline: {
|
||||
Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
click(e) {
|
||||
if (this.loading || this.disabled) {
|
||||
return;
|
||||
}
|
||||
this.$emit('click', e)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
className() {
|
||||
let name = "jl-button"
|
||||
if (this.inline) {
|
||||
name += ' inline'
|
||||
}
|
||||
if (this.disabled) {
|
||||
name += ' disabled'
|
||||
}
|
||||
if (this.loading) {
|
||||
name += " loading"
|
||||
}
|
||||
if (this.type) {
|
||||
name += " " + this.type
|
||||
}
|
||||
return name
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.jl-button {
|
||||
display: inline-block;
|
||||
padding: 15rpx 47rpx;
|
||||
border-radius: 10rpx;
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
color: #666666;
|
||||
border: 1rpx solid #c8c7cc;
|
||||
}
|
||||
|
||||
.jl-button.inline {
|
||||
display: block;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.jl-button.primary {
|
||||
color: #fefefe;
|
||||
background-color: #1b66ff;
|
||||
border-color: #1b66ff;
|
||||
}
|
||||
|
||||
.jl-button.loading,
|
||||
.jl-button.disabled {
|
||||
opacity: 0.3;
|
||||
}
|
||||
</style>
|
||||
@@ -1,39 +0,0 @@
|
||||
<template>
|
||||
<view class="jl-form-item">
|
||||
<view class="jl-form-item__label">{{prop}}</view>
|
||||
<view class="jl-form-item__content">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
prop: String,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.jl-form-item {
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.jl-form-item__label {
|
||||
float: left;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
letter-spacing: 0;
|
||||
line-height: 88rpx;
|
||||
}
|
||||
|
||||
.jl-form-item__content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.jl-form-item__content .jl-input-intext {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,15 +0,0 @@
|
||||
<template>
|
||||
<view class="jl-form">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.jl-form {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
@@ -1,92 +0,0 @@
|
||||
<template>
|
||||
<view class="jl-input">
|
||||
<input class="jl-input-intext" :type="type" :password="pwShow" :value="value" :placeholder="placeholder"
|
||||
:placeholder-class="placeholderClass" @input="setValue" @blur="setValue" @confirm="$emit('confirm')" :maxlength="maxlength" />
|
||||
<slot></slot>
|
||||
<slot name="icon"></slot>
|
||||
<image v-if="showPassword && pwShow" class="jl-input_image_eye" src="/static/img/eyeopen.svg" mode="" @click="changePasType"></image>
|
||||
<image v-else-if="showPassword" class="jl-input_image_eye" src="/static/img/eyeclosed.svg" mode="" @click="changePasType"></image>
|
||||
<image v-if="clearable" class="jl-input_image_delete" src="/static/img/delate.svg" mode="" @click="delpas"></image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
maxlength: {
|
||||
type: Number,
|
||||
default: -1
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "text",
|
||||
},
|
||||
placeholderClass: {
|
||||
type: String,
|
||||
default: "jl-input-inPla",
|
||||
},
|
||||
placeholder: String,
|
||||
value: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
clearable: Boolean,
|
||||
showPassword: Boolean,
|
||||
},
|
||||
computed: {},
|
||||
data() {
|
||||
return {
|
||||
pwShow: this.showPassword
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setValue(e) {
|
||||
this.$emit("input", e.detail.value);
|
||||
},
|
||||
delpas() {
|
||||
this.$emit("input", '');
|
||||
},
|
||||
changePasType() {
|
||||
this.pwShow = !this.pwShow
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.jl-input {
|
||||
margin: 0 auto;
|
||||
/* margin-top: 30rpx; */
|
||||
border-bottom: 1rpx solid #dddddd;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
opacity: hidden;
|
||||
}
|
||||
|
||||
.jl-input-intext {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 1rem;
|
||||
padding: 30rpx 0;
|
||||
color: #333333;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.jl-input-inPla {
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 1rem;
|
||||
color: #d8d8d8;
|
||||
}
|
||||
|
||||
.jl-input_image_delete {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.jl-input_image_eye {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -1,296 +0,0 @@
|
||||
<template>
|
||||
<uni-popup :custom="true" type="bottom" ref="keyboardPackage">
|
||||
<view class="keyboardbox">
|
||||
<view class="numkeyboard" v-if="type==='number'">
|
||||
<view class="num-area">
|
||||
<view class="row" v-for="(item,index) in numKeybordList" :key="index">
|
||||
<view :class="['item',ite===0?'z':'',(disableDot && ite==='.')?'disabled':'']" v-for="(ite,idx) in item"
|
||||
hover-class="active" :hover-start-time="0" :hover-stay-time="5" :key="idx" @tap="input(ite)">{{ite}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn-area">
|
||||
<view :class="['item','del']" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="deleteVal">
|
||||
删除
|
||||
</view>
|
||||
<view class="confirem item" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="confirm">
|
||||
完成
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="numkeyboard" v-if="type==='idCard'">
|
||||
<view class="num-area">
|
||||
<view class="row" v-for="(item,index) in idCardList" :key="index">
|
||||
<view :class="['item',ite===0?'z':'',(disableDot && ite==='.')?'disabled':'']" v-for="(ite,idx) in item"
|
||||
hover-class="active" :hover-start-time="0" :hover-stay-time="5" :key="idx" @tap="input(ite)">{{ite}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn-area">
|
||||
<view :class="['item','del']" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="deleteVal">
|
||||
删除
|
||||
</view>
|
||||
<view class="confirem item" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="confirm">
|
||||
完成
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="platenumber" v-if="type==='plateNumber'">
|
||||
<view class="header">
|
||||
<view @tap="active=active===1?2:1" hover-class="active" :hover-start-time="0" :hover-stay-time="5">{{active===1?'地区':'车牌号'}}</view>
|
||||
<view hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="confirm">完成</view>
|
||||
</view>
|
||||
<view class="main">
|
||||
<view class="normal" v-if="active===1">
|
||||
<view class="row" v-for="(item,index) in EngKeyBoardList" :key="index">
|
||||
<view class="item" v-for="(ite,idx) in item" :key="idx" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="input(ite)">
|
||||
{{ite}}
|
||||
</view>
|
||||
<view class="item img" v-if="index===EngKeyBoardList.length-1" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="deleteVal">
|
||||
<image src="/static/delete.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="area" v-if="active===2">
|
||||
<view class="row" v-for="(item,index) in areaList" :key="index">
|
||||
<view class="item" v-for="(ite,idx) in item" :key="idx" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="input(ite)">
|
||||
{{ite}}
|
||||
</view>
|
||||
<view class="item img" v-if="index===EngKeyBoardList.length-1" hover-class="active" :hover-start-time="0" :hover-stay-time="5" @tap="deleteVal">
|
||||
<image src="/static/delete.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="safe-area" v-if="safeAreaInsetBottom"></view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniPopup from "@/components/uni-popup/uni-popup.vue"
|
||||
export default {
|
||||
components: {
|
||||
uniPopup
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'number'
|
||||
},
|
||||
safeAreaInsetBottom: { //是否设置安全区
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disableDot: { //数字键盘是否禁止点击.仅type为number生效
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
numKeybordList: [
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9],
|
||||
[0, '.']
|
||||
],
|
||||
idCardList: [
|
||||
[1, 2, 3],
|
||||
[4, 5, 6],
|
||||
[7, 8, 9],
|
||||
[0, 'X']
|
||||
],
|
||||
areaList: [
|
||||
['京', '沪', '粤', '津', '冀', '豫', '云', '辽', '黑', '湘'],
|
||||
['皖', '鲁', '苏', '浙', '赣', '鄂', '桂', '甘', '晋', '陕'],
|
||||
['蒙', '吉', '闽', '贵', '渝', '川', '青', '琼', '宁'],
|
||||
['藏', '新', '使', '港', '澳', '学']
|
||||
],
|
||||
EngKeyBoardList: [
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0],
|
||||
['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],
|
||||
['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],
|
||||
['Z', 'X', 'C', 'V', 'B', 'N', 'M']
|
||||
],
|
||||
active: 1
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.$refs.keyboardPackage.open();
|
||||
},
|
||||
confirm() {
|
||||
this.close();
|
||||
this.$emit('onConfirm');
|
||||
},
|
||||
deleteVal() {
|
||||
this.$emit('onDelete');
|
||||
},
|
||||
input(val) {
|
||||
if (val === '.' && this.disableDot) return;
|
||||
this.$emit('onInput', val);
|
||||
},
|
||||
close() {
|
||||
this.$refs.keyboardPackage.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.keyboardbox {
|
||||
background-color: #FFFFFF;
|
||||
|
||||
.numkeyboard {
|
||||
height: 432rpx;
|
||||
display: flex;
|
||||
background-color: #ebedf0;
|
||||
|
||||
.btn-area {
|
||||
width: 180rpx;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.del {
|
||||
background-color: #ebedf0;
|
||||
color: #333;
|
||||
|
||||
&.active {
|
||||
background-color: #f1f3f5;
|
||||
}
|
||||
}
|
||||
|
||||
.confirem {
|
||||
background-color: #1989fa;
|
||||
color: #FFFFFF;
|
||||
|
||||
&.active {
|
||||
background-color: #0570db;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.num-area {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.row {
|
||||
width: 100%;
|
||||
height: 25%;
|
||||
display: flex;
|
||||
margin-top: 1px;
|
||||
|
||||
.item {
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #FFFFFF;
|
||||
border-right: 1px solid #ebedf0;
|
||||
width: 33.33%;
|
||||
|
||||
&.active {
|
||||
background-color: #ebedf0;
|
||||
}
|
||||
|
||||
&.z {
|
||||
flex-grow: 2;
|
||||
width: 66.66%;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background: #FFFFFF;
|
||||
color: #B9B9B9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.safe-area {
|
||||
padding-bottom: 0rpx;
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.platenumber {
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.header {
|
||||
height: 76rpx;
|
||||
background-color: #FFFFFF;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 28rpx;
|
||||
border-top: 1px solid #f5f5f5;
|
||||
|
||||
&>view {
|
||||
padding: 0 45rpx;
|
||||
color: #00a7ea;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&.active {
|
||||
background-color: #ebedf0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
height: 435rpx;
|
||||
|
||||
.row {
|
||||
margin: 13rpx 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.item {
|
||||
width: 56rpx;
|
||||
height: 94rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 6rpx;
|
||||
margin: 0 7rpx;
|
||||
font-size: 24rpx;
|
||||
&.active {
|
||||
background-color: #ebedf0;
|
||||
}
|
||||
|
||||
&.img {
|
||||
background-color: #c2cacc;
|
||||
width: 94rpx;
|
||||
|
||||
&.active {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
&>image {
|
||||
width: 49rpx;
|
||||
height: 48rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,59 +0,0 @@
|
||||
const defaultOptions = {
|
||||
only: true
|
||||
}
|
||||
|
||||
|
||||
export default function markSlideListController(options = defaultOptions) {
|
||||
const instances = {};
|
||||
const opened = {};
|
||||
const moving = {};
|
||||
let index = 0;
|
||||
const pipelines = {
|
||||
moving: [],
|
||||
opened: [],
|
||||
closed: [],
|
||||
};
|
||||
init()
|
||||
|
||||
function init() {
|
||||
if (options.only) {
|
||||
pipelines.moving.push(only)
|
||||
}
|
||||
}
|
||||
|
||||
function pipelinesHandler(type, key) {
|
||||
pipelines[type].forEach(item => {
|
||||
item.call(this, key)
|
||||
})
|
||||
}
|
||||
|
||||
function only() {
|
||||
for (let key in opened) {
|
||||
const item = opened[key]
|
||||
item.hide()
|
||||
}
|
||||
}
|
||||
this.reg = ({
|
||||
instance,
|
||||
cb
|
||||
}) => {
|
||||
instances[index] = instance
|
||||
cb(index++)
|
||||
}
|
||||
|
||||
this.moving = (key) => {
|
||||
moving[key] = instances[key]
|
||||
delete opened[key]
|
||||
pipelinesHandler('moving', key)
|
||||
}
|
||||
this.opened = (key) => {
|
||||
opened[key] = instances[key]
|
||||
delete moving[key]
|
||||
pipelinesHandler('opened', key)
|
||||
}
|
||||
this.closed = (key) => {
|
||||
delete opened[key]
|
||||
delete moving[key]
|
||||
pipelinesHandler('closed', key)
|
||||
}
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
<template>
|
||||
<view class="slide-list">
|
||||
<view class="slide-list-item" @touchstart="touchStart" @touchend="touchEnd" @touchmove="touchMove" :style="{transform}">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view class="group-btn">
|
||||
<view class="btn-div" v-for="(btn, key) in button" :key="key" @click.stop="btnClick(btn,key)" :style="{background: btn.background}">
|
||||
<text class="btn-title">{{btn.title}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import handler from './slideHandler.js'
|
||||
/**
|
||||
* m-slide-list 滑动操作列表
|
||||
* @description 滑动操作列表组件
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=209
|
||||
* @property {Array} list 数据源,格式为:[{title: 'xxx', image:'xxx', surname: 'xxx',detail:'xxx', rightDetail: 'xxx', slide_x: 0},{title: 'xxx', image:'xxx', surname: 'xxx',detail:'xxx', rightDetail: 'xxx', slide_x: 0}]
|
||||
* @property {Array} button 按钮数据源,格式为:[{title: 'xxx', background:'xxx'},{title: 'xxx', background:'xxx'}]
|
||||
* @property {Boolean} border 边框
|
||||
*/
|
||||
export default {
|
||||
name: 'mark-slide-list',
|
||||
props: {
|
||||
button: { //按钮数据list
|
||||
type: Array,
|
||||
default () {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
windowWidth() {
|
||||
return uni.getSystemInfoSync().windowWidth;
|
||||
},
|
||||
transform() {
|
||||
return `translate3d(${ this.slide_x }px, 0, 0)`
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
key: null,
|
||||
moving: false,
|
||||
btnState: 'hide',
|
||||
hideLimit: 0,
|
||||
showLimit: 0,
|
||||
btnWidth: 0,
|
||||
slide_x: 0,
|
||||
handler: null
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$emit('controller-reg', {
|
||||
instance:{
|
||||
show: this.show,
|
||||
hide: this.hide
|
||||
},
|
||||
cb: (key) => {
|
||||
this.key = key
|
||||
}
|
||||
})
|
||||
const cb = res => {
|
||||
this.btnWidth = res[0].width * -1;
|
||||
this.showLimit = res[0].width / 3;
|
||||
this.hideLimit = res[0].width / 3;
|
||||
}
|
||||
// 按钮宽度
|
||||
uni.createSelectorQuery().in(this).select('.group-btn').boundingClientRect().exec(cb);
|
||||
},
|
||||
methods: {
|
||||
btnClick(btn, key) {
|
||||
this.$emit(btn.clickName, {
|
||||
btn,
|
||||
key
|
||||
})
|
||||
},
|
||||
setSlideX(offset) {
|
||||
const val = offset + this.slide_x
|
||||
if (val < 0 && val >= this.btnWidth) {
|
||||
this.slide_x = val
|
||||
} else if (val > 0) {
|
||||
this.slide_x = 0
|
||||
}
|
||||
},
|
||||
// 滑动开始
|
||||
touchStart(e) {
|
||||
this.$emit('controller-moving', this.key)
|
||||
this.moving = true
|
||||
this.handler = new handler(e.timeStamp, e.touches[0].pageX, e.touches[0].pageY)
|
||||
},
|
||||
// 滑动中
|
||||
touchMove(e) {
|
||||
const slide_x = this.handler.move(e.touches[0])
|
||||
this.setSlideX(slide_x)
|
||||
},
|
||||
// 滑动结束
|
||||
touchEnd(e) {
|
||||
this.moving = false
|
||||
const endTime = e.timeStamp,
|
||||
endY = e.changedTouches[0].pageY,
|
||||
endX = e.changedTouches[0].pageX;
|
||||
const x_end_distance = this.startX - this.lastX;
|
||||
const end = this.handler.endMove(endTime, endX, endY)
|
||||
if (end.invalid) {} else if ((end.quick && end.dir === 'l') || (end.dir === 'l' && end.move > this.showLimit)) {
|
||||
this.show()
|
||||
} else if ((end.quick && end.dir === 'r') || (end.dir === 'r' && end.move > this.hideLimit)) {
|
||||
this.hide()
|
||||
} else {
|
||||
this.recover()
|
||||
}
|
||||
this.handler = null
|
||||
},
|
||||
// 点击回复原状
|
||||
recover() {
|
||||
if (this.btnState === 'show') {
|
||||
this.show()
|
||||
} else if (this.btnState === 'hide') {
|
||||
this.hide()
|
||||
}
|
||||
},
|
||||
show() {
|
||||
this.btnState = 'show'
|
||||
this.slide_x = this.btnWidth;
|
||||
this.$emit('controller-opened', this.key)
|
||||
},
|
||||
hide() {
|
||||
this.btnState = 'hide'
|
||||
this.slide_x = 0;
|
||||
this.$emit('controller-closed', this.key)
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.slide-list {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.slide-list-item {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
transition: all 100ms;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
|
||||
.group-btn {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
min-width: 100rpx;
|
||||
align-items: center;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.btn-div {
|
||||
height: 100%;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
padding: 0 50rpx;
|
||||
font-size: 34rpx;
|
||||
display: table;
|
||||
|
||||
.btn-title {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.top {
|
||||
background-color: #c4c7cd;
|
||||
}
|
||||
|
||||
.removeM {
|
||||
background-color: #ff3b32;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -1,54 +0,0 @@
|
||||
class handler {
|
||||
|
||||
constructor(startTime, startX, startY) {
|
||||
this.startTime = startTime
|
||||
this.lastX = this.startX = startX
|
||||
this.startY = startY
|
||||
this._moveFunc = this.firstMove
|
||||
}
|
||||
|
||||
move({
|
||||
timeStamp,
|
||||
pageX,
|
||||
pageY
|
||||
}) {
|
||||
return this._moveFunc(timeStamp, pageX, pageY)
|
||||
}
|
||||
|
||||
|
||||
firstMove(timeStamp, pageX, pageY) {
|
||||
if (Math.abs(pageX - this.startX) > Math.abs(pageY - this.startY)) {
|
||||
this._moveFunc = this.nextMove
|
||||
} else {
|
||||
this._moveFunc = () => {
|
||||
return 0
|
||||
}
|
||||
this.endMove = () => {
|
||||
return {
|
||||
invalid: true
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
nextMove(timeStamp, pageX, pageY) {
|
||||
const r = pageX - this.lastX
|
||||
this.lastX = pageX
|
||||
return r
|
||||
}
|
||||
|
||||
isQuick(endTime, endX) {
|
||||
return endTime - this.startTime < 200 && Math.abs(endX - this.startX) > 50
|
||||
}
|
||||
|
||||
endMove(endTime, pageX, pageY) {
|
||||
return {
|
||||
invalid: false,
|
||||
quick: this.isQuick(endTime, pageX),
|
||||
dir: pageX > this.startX ? 'r' : 'l',
|
||||
move: Math.abs(pageX - this.startX)
|
||||
}
|
||||
}
|
||||
}
|
||||
export default handler
|
||||
@@ -1,120 +0,0 @@
|
||||
<template>
|
||||
<!-- 首字母检索 -->
|
||||
<view>
|
||||
<view class="letter touch" @touchstart.stop="searchStart" @touchmove.stop="searchMove" @touchend.stop="searchEnd">
|
||||
<!-- 右边字母数据数据 触摸事件-->
|
||||
<view class="letter-item" v-for="item in options" :key="item.key">{{item.key}}</view>
|
||||
<!-- 左边字母跟右边字母true时 屏幕中心显示选中的首字母-->
|
||||
</view>
|
||||
<!-- 居中首字母样式 -->
|
||||
<view class="cont-letter" v-if="isShowLetter">
|
||||
{{showLetter}}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
options: {
|
||||
type: Array
|
||||
},
|
||||
length: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
data() {
|
||||
let windowHeight = uni.getSystemInfoSync().windowHeight
|
||||
let startHeight = windowHeight * 0.1
|
||||
return {
|
||||
startHeight,
|
||||
letterHeight: windowHeight - startHeight,
|
||||
isShowLetter: false,
|
||||
showLetter: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
letters() {
|
||||
const arr = []
|
||||
for (let key in this.options) {
|
||||
arr.push(this.options[key])
|
||||
}
|
||||
return arr.key
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getLetter(pageY) {
|
||||
let index = ((pageY - this.startHeight) / this.letterHeight) * this.options.length
|
||||
return this.options[parseInt(index)].key
|
||||
},
|
||||
/* 检索字母拖动开始 */
|
||||
searchStart(e) {
|
||||
let pageY = e.touches[0].clientY;
|
||||
this.showLetter = this.getLetter(pageY);
|
||||
this.$emit("touchmove", this.showLetter)
|
||||
this.isShowLetter = true
|
||||
return false
|
||||
},
|
||||
/* 检索字母拖动中 */
|
||||
searchMove(e) {
|
||||
let pageY = e.touches[0].clientY;
|
||||
this.showLetter = this.getLetter(pageY);
|
||||
this.$emit("touchmove", this.showLetter)
|
||||
return false
|
||||
},
|
||||
/* 检索字母拖动结束 */
|
||||
searchEnd() {
|
||||
setTimeout(() => {
|
||||
this.isShowLetter = false
|
||||
}, 1000)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 首字母样式 */
|
||||
.letter {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 10%;
|
||||
width: 30px;
|
||||
height: 90%;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #666;
|
||||
background-color: transparent;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 右边首字母样式 */
|
||||
.touch {
|
||||
color: #666;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.letter-item {
|
||||
color: #1B66FF;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
/* 居中显示的选中首字母 */
|
||||
.cont-letter {
|
||||
background-color: #666;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -50px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 10px;
|
||||
font-size: 26px;
|
||||
z-index: 1
|
||||
}
|
||||
</style>
|
||||
@@ -1,192 +0,0 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 搜索框 -->
|
||||
<view class='search'>
|
||||
搜索<input type='text' v-model="keyValue" placeholder='请输入银行名称' placeholder-style="font-size:32rpx;color:#cccccc" />
|
||||
</view>
|
||||
<scroll-view ref="view" scroll-y="true" :scroll-top="scrollTop" :style="{height:`${winHeight}px`}">
|
||||
<!-- 循环城市数据 -->
|
||||
<view v-for="group in data.data" :key="group.key">
|
||||
<!-- 循环首字母检索信息 -->
|
||||
<view class="list_letter">{{group.key}}</view>
|
||||
<!-- 城市ID城市名称 -->
|
||||
<view class="item_city" v-for="item in group.value" :key="item.id" @tap="click(item)">{{item.name}}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<letter-list :options="data.letters" @touchmove="setScrollTop"></letter-list>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import letterList from './letter-list.vue'
|
||||
|
||||
function getFirstLetter(str) {
|
||||
return str[0];
|
||||
}
|
||||
|
||||
function fortmat(data, itemH, tHeight) {
|
||||
let index = 0
|
||||
const letters = []
|
||||
const scrollTop = {}
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
const value = data[i].value
|
||||
const key = data[i].key
|
||||
letters.push({
|
||||
key,
|
||||
value: value.length
|
||||
})
|
||||
scrollTop[key] = index
|
||||
index += value.length
|
||||
}
|
||||
return {
|
||||
data,
|
||||
letters,
|
||||
scrollTop
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
letterList
|
||||
},
|
||||
name: "NynCityList",
|
||||
props: {
|
||||
options: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
prop: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
name: 'name'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
keyValue: '',
|
||||
itemH: 0, //字母列表的高度
|
||||
scrollTop: 0,
|
||||
tHeight: 0,
|
||||
winHeight: 0, //城市列表窗口高度
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
mounted() {
|
||||
this.initList()
|
||||
},
|
||||
methods: {
|
||||
/* 列表初始化 */
|
||||
initList() {
|
||||
const sysInfo = uni.getSystemInfoSync();
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select(".item_city").boundingClientRect(scrollx=>{
|
||||
this.itemH = scrollx.height
|
||||
})
|
||||
query.select(".list_letter").boundingClientRect(scrollx=>{
|
||||
this.tHeight = scrollx.height
|
||||
})
|
||||
query.select('.search').boundingClientRect(data => {
|
||||
let top = data.height
|
||||
this.winHeight = sysInfo.windowHeight - top - 1;
|
||||
}).exec();
|
||||
},
|
||||
click(item) {
|
||||
this.$emit('change', item)
|
||||
},
|
||||
/* 设置scroll-view滚动距离 */
|
||||
setScrollTop(showLetter) {
|
||||
var letters = this.data.letters
|
||||
var letterIndex = 0
|
||||
for (var i = 0; i < letters.length; i++) {
|
||||
if (showLetter === letters[i].key) {
|
||||
letterIndex = i
|
||||
}
|
||||
}
|
||||
this.scrollTop = (this.data.scrollTop[showLetter] * this.itemH) + (letterIndex * this.tHeight)
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
data() {
|
||||
return fortmat(this.options, this.itemH, this.tHeight)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
keyValue(value) {
|
||||
this.$emit('filter-method', value)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
background-color: #ffffff;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
// border-radius:100rpx;
|
||||
|
||||
padding: 20rpx 0;
|
||||
width: 730rpx;
|
||||
margin-left: 20rpx;
|
||||
border-bottom: 1rpx solid #ddd;
|
||||
|
||||
input {
|
||||
line-height: 60rpx;
|
||||
text-align: left;
|
||||
padding-left: 20rpx;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 32rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 循环数据首字母检索 */
|
||||
.list_letter {
|
||||
display: flex;
|
||||
background-color: #f8f8f8;
|
||||
height: 60rpx;
|
||||
color: #2a2a2a;
|
||||
font-size: 26rpx;
|
||||
padding-left: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 城市样式 */
|
||||
.item_city {
|
||||
display: flex;
|
||||
background-color: #fff;
|
||||
height: 60rpx;
|
||||
font-family: PingFangSC-Regular;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
letter-spacing: 0;
|
||||
align-items: center;
|
||||
padding: 10rpx 0;
|
||||
width: 730rpx;
|
||||
margin-left: 20rpx;
|
||||
border-bottom: 2rpx solid #ddd;
|
||||
}
|
||||
|
||||
.list {
|
||||
.eng {
|
||||
background: #ffffff;
|
||||
padding: 30rpx;
|
||||
color: #212121;
|
||||
}
|
||||
|
||||
.text {
|
||||
color: #212121;
|
||||
font-size: 26rpx;
|
||||
margin: 30rpx 0 0 30rpx;
|
||||
padding-bottom: 30rpx;
|
||||
border-bottom: 1px solid #E6E6E6
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,168 +0,0 @@
|
||||
<!--
|
||||
自定义验证码输入、密码输入使用
|
||||
|
||||
使用方法:
|
||||
maxlength:输入最大长度
|
||||
isPwd:是否是密码模式
|
||||
@finish:回调函数
|
||||
<validcode :maxlength="4" :isPwd="false" @finish="finish"></validcode>
|
||||
-->
|
||||
<template>
|
||||
<view class="code-area">
|
||||
<view class="flex-box">
|
||||
<input :value="val" type="number" :focus="true" :maxlength="maxlength" class="hide-input" @input="getVal" @focus="focus"
|
||||
@blur="blur" />
|
||||
<view :key="index" v-for="(i,index) in maxlength - 1" v-bind:class="['item', { active: focusing && codeIndex === index }]">
|
||||
<view class="line"></view>
|
||||
<block v-if="val.length - 1 < index"></block>
|
||||
<block v-else-if="isPwd">
|
||||
<text class="dot">.</text>
|
||||
</block>
|
||||
<block v-else> {{ val[index] }}</block>
|
||||
</view>
|
||||
<view v-bind:class="['item', { active: focusing && codeIndex >= maxlength - 1 }]">
|
||||
<view class="line" v-if="val.length - 1 < maxlength - 1"></view>
|
||||
<block v-else-if="isPwd">
|
||||
<text class="dot">.</text>
|
||||
</block>
|
||||
<block v-else> {{ val[maxlength - 1] }}</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
//最大长度 值为4或者6
|
||||
maxlength: {
|
||||
type: Number,
|
||||
default: 4
|
||||
},
|
||||
//是否是密码
|
||||
isPwd: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
focusing: true,
|
||||
val: '', //输入框的值
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
//取值
|
||||
getVal(e) {
|
||||
let {
|
||||
value
|
||||
} = e.detail;
|
||||
if (value.length <= this.maxlength) {
|
||||
this.val = value;
|
||||
}
|
||||
},
|
||||
//清除验证码或者密码
|
||||
clear() {
|
||||
this.val = "";
|
||||
},
|
||||
blur() {
|
||||
this.focusing = false
|
||||
},
|
||||
focus() {
|
||||
this.focusing = true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
codeIndex() {
|
||||
return this.val.length
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
val(val) {
|
||||
if (val.length === this.maxlength) {
|
||||
this.$emit('finish', val);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.code-area {
|
||||
text-align: center;
|
||||
|
||||
.flex-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
position: relative;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
width: 80upx;
|
||||
height: 80upx;
|
||||
margin-right: 18upx;
|
||||
font-size: 30upx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
line-height: 80upx;
|
||||
box-sizing: border-box;
|
||||
border: 2upx solid #cccccc;
|
||||
}
|
||||
|
||||
.item:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.active {
|
||||
border-color: #1B66FF
|
||||
}
|
||||
|
||||
.active .line {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.line {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 2upx;
|
||||
height: 40upx;
|
||||
background: #1B66FF;
|
||||
animation: twinkling 1s infinite ease;
|
||||
}
|
||||
|
||||
.hide-input {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 200%;
|
||||
height: 100%;
|
||||
text-align: left;
|
||||
z-index: 9;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@keyframes twinkling {
|
||||
0% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
.dot {
|
||||
font-size: 80upx;
|
||||
line-height: 40upx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,69 +0,0 @@
|
||||
<template>
|
||||
<view class="stepBarWrap">
|
||||
<view class="stepBarContent" v-for="(item, index) in stepList" :key="index" >
|
||||
<view class="number" :class="{'activeNum':active >= index}">{{index+1}}</view>
|
||||
<view :class="{'active':active >= index}" style="color: #979797;margin-top: 20rpx;">{{item}}</view>
|
||||
<view class="br" v-if="index > 0" :class="{'activeBr': active>=index}"></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data (){
|
||||
return {
|
||||
}
|
||||
},
|
||||
props: {
|
||||
stepList: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
active: 0
|
||||
},
|
||||
methods:{
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.stepBarWrap{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 15px;
|
||||
}
|
||||
.stepBarContent{
|
||||
flex:1;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
}
|
||||
.stepBarContent .number{
|
||||
width:60rpx;
|
||||
height: 60rpx;
|
||||
line-height: 30px;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
background-color: #97979747;
|
||||
}
|
||||
.stepBarContent .br{
|
||||
width: 40%;
|
||||
height:2px;
|
||||
background-color: #979797;
|
||||
position: absolute;
|
||||
top: 28%;
|
||||
left: -20%;
|
||||
}
|
||||
.active{
|
||||
color: #1C66FF !important;
|
||||
}
|
||||
.activeNum{
|
||||
background-color: #1C66FF !important;
|
||||
}
|
||||
.activeBr{
|
||||
background-color: #1C66FF !important;
|
||||
}
|
||||
</style>
|
||||
@@ -1,96 +0,0 @@
|
||||
export default {
|
||||
'contact': '\ue100',
|
||||
'person': '\ue101',
|
||||
'personadd': '\ue102',
|
||||
'contact-filled': '\ue130',
|
||||
'person-filled': '\ue131',
|
||||
'personadd-filled': '\ue132',
|
||||
'phone': '\ue200',
|
||||
'email': '\ue201',
|
||||
'chatbubble': '\ue202',
|
||||
'chatboxes': '\ue203',
|
||||
'phone-filled': '\ue230',
|
||||
'email-filled': '\ue231',
|
||||
'chatbubble-filled': '\ue232',
|
||||
'chatboxes-filled': '\ue233',
|
||||
'weibo': '\ue260',
|
||||
'weixin': '\ue261',
|
||||
'pengyouquan': '\ue262',
|
||||
'chat': '\ue263',
|
||||
'qq': '\ue264',
|
||||
'videocam': '\ue300',
|
||||
'camera': '\ue301',
|
||||
'mic': '\ue302',
|
||||
'location': '\ue303',
|
||||
'mic-filled': '\ue332',
|
||||
'speech': '\ue332',
|
||||
'location-filled': '\ue333',
|
||||
'micoff': '\ue360',
|
||||
'image': '\ue363',
|
||||
'map': '\ue364',
|
||||
'compose': '\ue400',
|
||||
'trash': '\ue401',
|
||||
'upload': '\ue402',
|
||||
'download': '\ue403',
|
||||
'close': '\ue404',
|
||||
'redo': '\ue405',
|
||||
'undo': '\ue406',
|
||||
'refresh': '\ue407',
|
||||
'star': '\ue408',
|
||||
'plus': '\ue409',
|
||||
'minus': '\ue410',
|
||||
'circle': '\ue411',
|
||||
'checkbox': '\ue411',
|
||||
'close-filled': '\ue434',
|
||||
'clear': '\ue434',
|
||||
'refresh-filled': '\ue437',
|
||||
'star-filled': '\ue438',
|
||||
'plus-filled': '\ue439',
|
||||
'minus-filled': '\ue440',
|
||||
'circle-filled': '\ue441',
|
||||
'checkbox-filled': '\ue442',
|
||||
'closeempty': '\ue460',
|
||||
'refreshempty': '\ue461',
|
||||
'reload': '\ue462',
|
||||
'starhalf': '\ue463',
|
||||
'spinner': '\ue464',
|
||||
'spinner-cycle': '\ue465',
|
||||
'search': '\ue466',
|
||||
'plusempty': '\ue468',
|
||||
'forward': '\ue470',
|
||||
'back': '\ue471',
|
||||
'left-nav': '\ue471',
|
||||
'checkmarkempty': '\ue472',
|
||||
'home': '\ue500',
|
||||
'navigate': '\ue501',
|
||||
'gear': '\ue502',
|
||||
'paperplane': '\ue503',
|
||||
'info': '\ue504',
|
||||
'help': '\ue505',
|
||||
'locked': '\ue506',
|
||||
'more': '\ue507',
|
||||
'flag': '\ue508',
|
||||
'home-filled': '\ue530',
|
||||
'gear-filled': '\ue532',
|
||||
'info-filled': '\ue534',
|
||||
'help-filled': '\ue535',
|
||||
'more-filled': '\ue537',
|
||||
'settings': '\ue560',
|
||||
'list': '\ue562',
|
||||
'bars': '\ue563',
|
||||
'loop': '\ue565',
|
||||
'paperclip': '\ue567',
|
||||
'eye': '\ue568',
|
||||
'arrowup': '\ue580',
|
||||
'arrowdown': '\ue581',
|
||||
'arrowleft': '\ue582',
|
||||
'arrowright': '\ue583',
|
||||
'arrowthinup': '\ue584',
|
||||
'arrowthindown': '\ue585',
|
||||
'arrowthinleft': '\ue586',
|
||||
'arrowthinright': '\ue587',
|
||||
'pulldown': '\ue588',
|
||||
'closefill': '\ue589',
|
||||
'sound': '\ue590',
|
||||
'scan': '\ue612'
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<!-- #ifdef H5 || APP-PLUS -->
|
||||
<view class="jl-mask" v-if="maskShow" style="top: 44px;">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="jl-mask" v-if="maskShow">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
props: {
|
||||
maskShow: false
|
||||
},
|
||||
methods:{
|
||||
clear(e){
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.jl-mask{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0,0,0,.1);
|
||||
/* overflow: auto; */
|
||||
z-index: 999;
|
||||
}
|
||||
.maskClose{
|
||||
position: absolute;
|
||||
right: 100rpx;
|
||||
top: 100rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -1,206 +0,0 @@
|
||||
<template>
|
||||
<view class="uni-navbar">
|
||||
<view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }" :style="{ 'background-color': backgroundColor }"
|
||||
class="uni-navbar__content">
|
||||
<uni-status-bar v-if="statusBar" />
|
||||
<view :style="{ color: color,backgroundColor: backgroundColor }" class="uni-navbar__header uni-navbar__content_view">
|
||||
|
||||
<view class="uni-navbar__header-container uni-navbar__content_view">
|
||||
<view class="uni-navbar__header-container-inner uni-navbar__content_view" v-if="title.length">
|
||||
<text class="uni-nav-bar-text" :style="{color: color }">{{ title }}</text>
|
||||
</view>
|
||||
<!-- 标题插槽 -->
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-navbar__placeholder" v-if="fixed">
|
||||
<uni-status-bar v-if="statusBar" />
|
||||
<view class="uni-navbar__placeholder-view" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniStatusBar from "../uni-status-bar/uni-status-bar.vue";
|
||||
import uniIcons from "../uni-icons/uni-icons.vue";
|
||||
|
||||
export default {
|
||||
name: "UniNavBar",
|
||||
components: {
|
||||
uniStatusBar,
|
||||
uniIcons
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
leftText: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
rightText: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
leftIcon: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
rightIcon: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
fixed: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: "#000000"
|
||||
},
|
||||
backgroundColor: {
|
||||
type: String,
|
||||
default: "#FFFFFF"
|
||||
},
|
||||
statusBar: {
|
||||
type: [Boolean, String],
|
||||
default: false
|
||||
},
|
||||
shadow: {
|
||||
type: [String, Boolean],
|
||||
default: false
|
||||
},
|
||||
border: {
|
||||
type: [String, Boolean],
|
||||
default: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if(uni.report && this.title !== '') {
|
||||
uni.report('title', this.title)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClickLeft() {
|
||||
this.$emit("clickLeft");
|
||||
},
|
||||
onClickRight() {
|
||||
this.$emit("clickRight");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$nav-height: 44px;
|
||||
.uni-nav-bar-text {
|
||||
/* #ifdef APP-PLUS */
|
||||
font-size: 34rpx;
|
||||
/* #endif */
|
||||
/* #ifndef APP-PLUS */
|
||||
font-size: $uni-font-size-lg;
|
||||
/* #endif */
|
||||
}
|
||||
.uni-nav-bar-right-text {
|
||||
font-size: $uni-font-size-base;
|
||||
}
|
||||
|
||||
.uni-navbar {
|
||||
width: 750rpx;
|
||||
}
|
||||
|
||||
.uni-navbar__content {
|
||||
position: relative;
|
||||
width: 750rpx;
|
||||
background-color: $uni-bg-color;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-navbar__content_view {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
// background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.uni-navbar__header {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
width: 750rpx;
|
||||
height: $nav-height;
|
||||
line-height: $nav-height;
|
||||
font-size: 16px;
|
||||
justify-content: center;
|
||||
// background-color: #ffffff;
|
||||
}
|
||||
|
||||
.uni-navbar__header-btns {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-wrap: nowrap;
|
||||
width: 120rpx;
|
||||
padding: 0 6px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.uni-navbar__header-btns-left {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
width: 150rpx;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.uni-navbar__header-btns-right {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
width: 150rpx;
|
||||
padding-right: 30rpx;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.uni-navbar__header-container {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.uni-navbar__header-container-inner {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: $uni-font-size-base;
|
||||
}
|
||||
|
||||
|
||||
.uni-navbar__placeholder-view {
|
||||
height: $nav-height;
|
||||
}
|
||||
|
||||
.uni-navbar--fixed {
|
||||
position: fixed;
|
||||
z-index: 998;
|
||||
}
|
||||
|
||||
.uni-navbar--shadow {
|
||||
/* #ifndef APP-NVUE */
|
||||
box-shadow: 0 1px 6px #ccc;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-navbar--border {
|
||||
// border-bottom-width: 1rpx;
|
||||
// border-bottom-style: solid;
|
||||
// border-bottom-color: $uni-border-color;
|
||||
}
|
||||
</style>
|
||||
@@ -1,187 +0,0 @@
|
||||
<template>
|
||||
<view v-if="showPopup" class="uni-popup">
|
||||
<view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" />
|
||||
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper" @click="close(true)">
|
||||
<view class="uni-popup__wrapper-box" @click.stop="clear">
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UniPopup',
|
||||
props: {
|
||||
// 开启动画
|
||||
animation: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
|
||||
type: {
|
||||
type: String,
|
||||
default: 'center'
|
||||
},
|
||||
// 是否开启自定义
|
||||
custom: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// maskClick
|
||||
maskClick: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ani: '',
|
||||
showPopup: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(newValue) {
|
||||
if (newValue) {
|
||||
this.open()
|
||||
} else {
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
clear() {},
|
||||
open() {
|
||||
this.$emit('change', {
|
||||
show: true
|
||||
})
|
||||
this.showPopup = true
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.ani = 'uni-' + this.type
|
||||
}, 30)
|
||||
})
|
||||
},
|
||||
close(type) {
|
||||
if (!this.maskClick && type) return
|
||||
this.$emit('change', {
|
||||
show: false
|
||||
})
|
||||
this.ani = ''
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.showPopup = false
|
||||
}, 300)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
@charset "UTF-8";
|
||||
|
||||
.uni-popup {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 99999;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.uni-popup__mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 998;
|
||||
/* background: rgba(0, 0, 0, .4); */
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
.uni-popup__mask.ani {
|
||||
transition: all .3s
|
||||
}
|
||||
|
||||
.uni-popup__mask.uni-bottom,
|
||||
.uni-popup__mask.uni-center,
|
||||
.uni-popup__mask.uni-top {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
.uni-popup__wrapper {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.uni-popup__wrapper.ani {
|
||||
transition: all .3s
|
||||
}
|
||||
|
||||
.uni-popup__wrapper.top {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
transform: translateY(-100%)
|
||||
}
|
||||
|
||||
.uni-popup__wrapper.bottom {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
transform: translateY(100%)
|
||||
}
|
||||
|
||||
.uni-popup__wrapper.center {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transform: scale(1.2);
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
.uni-popup__wrapper-box {
|
||||
position: relative;
|
||||
box-sizing: border-box
|
||||
}
|
||||
|
||||
.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
|
||||
padding: 30upx;
|
||||
background: #fff
|
||||
}
|
||||
|
||||
.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
|
||||
position: relative;
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
overflow-y: scroll
|
||||
}
|
||||
|
||||
.uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box,
|
||||
.uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box {
|
||||
width: 100%;
|
||||
max-height: 500px;
|
||||
overflow-y: scroll
|
||||
}
|
||||
|
||||
.uni-popup__wrapper.uni-bottom,
|
||||
.uni-popup__wrapper.uni-top {
|
||||
transform: translateY(0)
|
||||
}
|
||||
|
||||
.uni-popup__wrapper.uni-center {
|
||||
transform: scale(1);
|
||||
opacity: 1
|
||||
}
|
||||
</style>
|
||||
@@ -1,346 +0,0 @@
|
||||
<template>
|
||||
<view class="sealWrapBox">
|
||||
<view class="wrapper" v-show="showCanvas">
|
||||
<view class="handBtn">
|
||||
<view class="lookBtn" @click="look">图例示范</view>
|
||||
<view class="delBtn" @click="clear">清除</view>
|
||||
<view v-if="paintBrush" class="saveBtn saveBtnActive" @click="finish">下一步</view>
|
||||
<view v-else class="saveBtn">下一步</view>
|
||||
<!-- <view class="previewBtn" @click="close">关闭</view> -->
|
||||
</view>
|
||||
|
||||
<view class="handCenter">
|
||||
<canvas v-show="!maskShow" canvas-id="canvasid" id="test" class="handWriting" disable-scroll="true" @touchstart="touchstart"
|
||||
@touchmove="touchmove" @touchend="touchend"></canvas>
|
||||
</view>
|
||||
<view class="handRight">
|
||||
<image src="../../pageMy/static/img/seal/tips.png" mode=""></image>
|
||||
<view class="handTitle">手写签名需与本人姓名保持一致</view>
|
||||
</view>
|
||||
</view>
|
||||
<uniMask :maskShow="maskShow">
|
||||
<view class="maskBody" :style="maskBodyStyle">
|
||||
<view class="closeMask" @click.stop="closeMask">关闭</view>
|
||||
</view>
|
||||
</uniMask>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
baseUrl
|
||||
} from '@/config/env.js'
|
||||
import {
|
||||
getStore
|
||||
} from '@/untils/store.js'
|
||||
import uniMask from '@/components/uni-mask/mask.vue'
|
||||
var x = 20;
|
||||
var y = 20;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
oc: "",
|
||||
src: "",
|
||||
//路径点集合
|
||||
points: [],
|
||||
maskBodyStyle: '',
|
||||
showCanvas: true,
|
||||
maskShow: false,
|
||||
paintBrush: false
|
||||
|
||||
};
|
||||
},
|
||||
components: {
|
||||
uniMask
|
||||
},
|
||||
mounted() {
|
||||
this.initCanvas()
|
||||
},
|
||||
methods: {
|
||||
look() {
|
||||
uni.getSystemInfo({
|
||||
success: res => {
|
||||
var scrollH = res.windowHeight
|
||||
var scrollW = res.windowWidth
|
||||
// #ifdef H5
|
||||
this.maskBodyStyle =
|
||||
`width:${scrollH-144}px;height:${scrollW-100}px;top:${(scrollW/2)+94}px;left:-${(scrollW-100)/2}px`
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
this.maskBodyStyle =
|
||||
`width:${scrollH-144}px;height:${scrollW-100}px;top:${(scrollW/2)}px;left:-${(scrollW-100)/2}px`
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
this.maskShow = true
|
||||
},
|
||||
closeMask() {
|
||||
this.maskShow = false
|
||||
},
|
||||
imgFile() {
|
||||
var token = getStore({
|
||||
name: 'token'
|
||||
})
|
||||
const that = this
|
||||
uni.uploadFile({
|
||||
url: `${baseUrl}/api/jobslink-api/resource/oss/endpoint/put-file?Jobslink-Auth=${token}`,
|
||||
filePath: that.src,
|
||||
name: 'file',
|
||||
success: (uploadFileRes) => {
|
||||
that.$emit('finish', uploadFileRes)
|
||||
that.paintBrush = true
|
||||
}
|
||||
});
|
||||
},
|
||||
finish() {
|
||||
const that = this
|
||||
this.paintBrush = false
|
||||
this.oc.draw(true, uni.canvasToTempFilePath({
|
||||
destWidth: 300,
|
||||
destHeight: 300,
|
||||
quality: 1,
|
||||
canvasId: 'canvasid',
|
||||
fileType: 'png',
|
||||
success: function(res) {
|
||||
that.src = res.tempFilePath
|
||||
that.imgFile()
|
||||
},
|
||||
fail: function(err) {
|
||||
console.log(err)
|
||||
}
|
||||
}, this))
|
||||
},
|
||||
close: function() {
|
||||
this.showCanvas = false;
|
||||
this.clear();
|
||||
},
|
||||
initCanvas() {
|
||||
this.showCanvas = true;
|
||||
this.oc = uni.createCanvasContext('canvasid', this);
|
||||
//设置画笔样式
|
||||
this.oc.lineWidth = 10;
|
||||
this.oc.lineCap = "round";
|
||||
this.oc.lineJoin = "round";
|
||||
// 画笔颜色
|
||||
// this.oc.setStrokeStyle("#ffffff");
|
||||
|
||||
},
|
||||
//触摸开始,获取到起点
|
||||
touchstart(e) {
|
||||
const startX = e.changedTouches[0].x;
|
||||
const startY = e.changedTouches[0].y;
|
||||
let startPoint = {
|
||||
X: startX,
|
||||
Y: startY
|
||||
};
|
||||
this.points.push(startPoint);
|
||||
//每次触摸开始,开启新的路径
|
||||
this.oc.beginPath();
|
||||
},
|
||||
//触摸移动,获取到路径点
|
||||
touchmove(e) {
|
||||
let moveX = e.changedTouches[0].x;
|
||||
let moveY = e.changedTouches[0].y;
|
||||
let movePoint = {
|
||||
X: moveX,
|
||||
Y: moveY
|
||||
};
|
||||
this.points.push(movePoint); //存点
|
||||
let len = this.points.length;
|
||||
if (len >= 2) {
|
||||
this.draw(); //绘制路径
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// 触摸结束,将未绘制的点清空防止对后续路径产生干扰
|
||||
touchend() {
|
||||
this.points = [];
|
||||
this.paintBrush = true
|
||||
},
|
||||
|
||||
/*
|
||||
# 绘制笔迹
|
||||
# 1.为保证笔迹实时显示,必须在移动的同时绘制笔迹
|
||||
# 2.为保证笔迹连续,每次从路径集合中区两个点作为起点(moveTo)和终点(lineTo)
|
||||
# 3.将上一次的终点作为下一次绘制的起点(即清除第一个点)
|
||||
*/
|
||||
draw() {
|
||||
let point1 = this.points[0]
|
||||
let point2 = this.points[1]
|
||||
this.points.shift()
|
||||
this.oc.moveTo(point1.X, point1.Y)
|
||||
this.oc.lineTo(point2.X, point2.Y)
|
||||
this.oc.stroke()
|
||||
this.oc.draw(true)
|
||||
},
|
||||
//清空画布
|
||||
clear() {
|
||||
let that = this;
|
||||
uni.getSystemInfo({
|
||||
success: function(res) {
|
||||
that.paintBrush = false
|
||||
let canvasw = res.windowWidth;
|
||||
let canvash = res.windowHeight;
|
||||
that.oc.clearRect(0, 0, canvasw, canvash);
|
||||
that.oc.draw(true);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
page {
|
||||
background: #fbfbfb;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.maskBody {
|
||||
position: fixed;
|
||||
transform: rotate(90deg);
|
||||
background: url(../../static/img/anli.png) no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.maskBody .closeMask {
|
||||
background-color: #FFFFFF;
|
||||
position: fixed;
|
||||
right: 16rpx;
|
||||
top: 12rpx;
|
||||
width: 108rpx;
|
||||
height: 45rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
line-height: 45rpx;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.sealWrapBox {
|
||||
background: #FFFFFF;
|
||||
padding: 15px;
|
||||
height: -webkit-fill-available;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.handWriting {
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.handRight {
|
||||
display: inline-flex;
|
||||
align-items: space-between;
|
||||
width: 100%;
|
||||
height: 50rpx;
|
||||
transform: rotate(90deg);
|
||||
position: absolute;
|
||||
left: 300rpx;
|
||||
bottom: 40%;
|
||||
|
||||
}
|
||||
|
||||
.handRight image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
|
||||
}
|
||||
|
||||
.handCenter {
|
||||
border-left: 4rpx dashed #e9e9e9;
|
||||
flex: 5;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.handTitle {
|
||||
flex: 1;
|
||||
color: #666;
|
||||
width: 100%;
|
||||
height: 40rpx;
|
||||
line-height: 40rpx;
|
||||
|
||||
}
|
||||
|
||||
.handBtn button {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.handBtn {
|
||||
height: 95vh;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-content: space-between;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.lookBtn {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: 0;
|
||||
transform: rotate(90deg);
|
||||
width: 128rpx;
|
||||
height: 45rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 400;
|
||||
color: #1C66FF;
|
||||
line-height: 45rpx;
|
||||
}
|
||||
|
||||
.delBtn {
|
||||
position: absolute;
|
||||
bottom: 90px;
|
||||
left: 0rpx;
|
||||
transform: rotate(90deg);
|
||||
color: #979797;
|
||||
width: 120rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.delBtn image {
|
||||
position: absolute;
|
||||
top: 13rpx;
|
||||
left: 25rpx;
|
||||
}
|
||||
|
||||
.saveBtnActive {
|
||||
background-color: #1C66FF !important;
|
||||
color: #FFFFFF !important;
|
||||
}
|
||||
|
||||
.saveBtn {
|
||||
position: absolute;
|
||||
bottom: 37px;
|
||||
left: 0rpx;
|
||||
transform: rotate(90deg);
|
||||
color: #979797;
|
||||
width: 120rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
text-align: center;
|
||||
background: #D6D6D6;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.previewBtn {
|
||||
position: absolute;
|
||||
top: 500rpx;
|
||||
left: 0rpx;
|
||||
transform: rotate(90deg);
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
@@ -1,183 +0,0 @@
|
||||
<template>
|
||||
<view class="uni-searchbar">
|
||||
<view :style="{borderRadius:radius+'px',backgroundColor: bgColor}" class="uni-searchbar__box" @click="searchClick">
|
||||
<!-- #ifdef MP-ALIPAY -->
|
||||
<view class="uni-searchbar__box-icon-search">
|
||||
<uni-icons color="#999999" size="18" type="search" />
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-ALIPAY -->
|
||||
<uni-icons color="#999999" class="uni-searchbar__box-icon-search" size="18" type="search" />
|
||||
<!-- #endif -->
|
||||
<input v-if="show" :focus="showSync" :placeholder="placeholder" :maxlength="maxlength" @confirm="confirm" class="uni-searchbar__box-search-input"
|
||||
confirm-type="search" type="text" v-model="searchVal" />
|
||||
<text v-else class="uni-searchbar__text-placeholder">{{ placeholder }}</text>
|
||||
<view v-if="show && (clearButton==='always'||clearButton==='auto'&&searchVal!=='')" class="uni-searchbar__box-icon-clear" @click="clear">
|
||||
<uni-icons color="#999999" class="" size="24" type="clear" />
|
||||
</view>
|
||||
</view>
|
||||
<text @click="cancel" class="uni-searchbar__cancel" v-if="cancelButton ==='always' || show && cancelButton ==='auto'">{{cancelText}}</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uniIcons from "../uni-icons/uni-icons.vue";
|
||||
export default {
|
||||
name: "UniSearchBar",
|
||||
components: {
|
||||
uniIcons
|
||||
},
|
||||
props: {
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "请输入搜索内容"
|
||||
},
|
||||
radius: {
|
||||
type: [Number, String],
|
||||
default: 5
|
||||
},
|
||||
clearButton: {
|
||||
type: String,
|
||||
default: "auto"
|
||||
},
|
||||
cancelButton: {
|
||||
type: String,
|
||||
default: "auto"
|
||||
},
|
||||
cancelText: {
|
||||
type: String,
|
||||
default: '取消'
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: "#F8F8F8"
|
||||
},
|
||||
maxlength: {
|
||||
type: [Number, String],
|
||||
default: 100
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
showSync: false,
|
||||
searchVal: ""
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
searchVal() {
|
||||
this.$emit("input", {
|
||||
value: this.searchVal
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
searchClick() {
|
||||
if (this.show) {
|
||||
return
|
||||
}
|
||||
this.searchVal = ""
|
||||
this.show = true;
|
||||
this.$nextTick(() => {
|
||||
this.showSync = true;
|
||||
})
|
||||
},
|
||||
clear() {
|
||||
this.searchVal = ""
|
||||
},
|
||||
cancel() {
|
||||
this.$emit("cancel", {
|
||||
value: this.searchVal
|
||||
});
|
||||
this.searchVal = ""
|
||||
this.show = false
|
||||
this.showSync = false
|
||||
// #ifndef APP-PLUS
|
||||
uni.hideKeyboard()
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
plus.key.hideSoftKeybord()
|
||||
// #endif
|
||||
},
|
||||
confirm() {
|
||||
// #ifndef APP-PLUS
|
||||
uni.hideKeyboard();
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
plus.key.hideSoftKeybord()
|
||||
// #endif
|
||||
this.$emit("confirm", {
|
||||
value: this.searchVal
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
$uni-searchbar-height: 36px;
|
||||
|
||||
.uni-searchbar {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
position: relative;
|
||||
padding: $uni-spacing-col-base;
|
||||
background-color: $uni-bg-color;
|
||||
}
|
||||
|
||||
.uni-searchbar__box {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
/* #endif */
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: $uni-searchbar-height;
|
||||
padding: 5px 8px 5px 0px;
|
||||
border-width: 0.5px;
|
||||
border-style: solid;
|
||||
border-color: $uni-border-color;
|
||||
}
|
||||
|
||||
.uni-searchbar__box-icon-search {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
width: 32px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: $uni-text-color-placeholder;
|
||||
}
|
||||
|
||||
.uni-searchbar__box-search-input {
|
||||
flex: 1;
|
||||
font-size: $uni-font-size-base;
|
||||
color: $uni-text-color;
|
||||
}
|
||||
|
||||
.uni-searchbar__box-icon-clear {
|
||||
align-items: center;
|
||||
line-height: 24px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.uni-searchbar__text-placeholder {
|
||||
font-size: $uni-font-size-base;
|
||||
color: $uni-text-color-placeholder;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.uni-searchbar__cancel {
|
||||
padding-left: 10px;
|
||||
line-height: $uni-searchbar-height;
|
||||
font-size: 14px;
|
||||
color: $uni-text-color;
|
||||
}
|
||||
</style>
|
||||
@@ -1,25 +0,0 @@
|
||||
<template>
|
||||
<view :style="{ height: statusBarHeight }" class="uni-status-bar">
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
var statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px'
|
||||
export default {
|
||||
name: 'UniStatusBar',
|
||||
data() {
|
||||
return {
|
||||
statusBarHeight: statusBarHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.uni-status-bar {
|
||||
width: 750rpx;
|
||||
height: 20px;
|
||||
// height: var(--status-bar-height);
|
||||
}
|
||||
</style>
|
||||
@@ -1,82 +0,0 @@
|
||||
## 调用方式
|
||||
|
||||
- 视图调用
|
||||
|
||||
```html
|
||||
<v-tabs
|
||||
:tabs="[1,2,3,4]"
|
||||
height="45px"
|
||||
v-model="activeTab"
|
||||
color="#333"
|
||||
activeColor="#1abc9c"
|
||||
fontSize="14px"
|
||||
activeFontSize="16px"
|
||||
:lineHeight="4px"
|
||||
:lineScale="0.8"
|
||||
lineColor="#1abc9c"
|
||||
/>
|
||||
```
|
||||
|
||||
- js 调用
|
||||
|
||||
```js
|
||||
import vTabs from '@/components/v-tabs'
|
||||
export default {
|
||||
components: {
|
||||
vTabs,
|
||||
},
|
||||
data() {
|
||||
activeTab: 0
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
- 参数说明
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
| :-------------: | :--------------: | :-----: | :----------: |
|
||||
| value | String 或 Number | 0 | 必传 |
|
||||
| tabs | Array | [] | tabs 数量 |
|
||||
| height | String | '45px' | tab 高度 |
|
||||
| backgroundColor | String | '' | 选中背景 |
|
||||
| borderRadius | String | 5px | 圆角 |
|
||||
| color | String | #333333 | 默认文字颜色 |
|
||||
| activeColor | String | #333333 | 选中文字颜色 |
|
||||
| fontSize | String | 14px | 默认文字大小 |
|
||||
| activeFontSize | String | 14px | 选中文字大小 |
|
||||
| lineScale | Number | 0.6 | 下划线缩放 |
|
||||
| lineHeight | [Number, String] | 3 | 下划线高度 |
|
||||
| lineColor | Sring | #007AFF | 下划线颜色 |
|
||||
|
||||
|
||||
## 事件
|
||||
|
||||
|事件名称|参数|
|
||||
|:-----:|:-----:|
|
||||
|@change|activeTab|
|
||||
|
||||
|
||||
## 更新日志
|
||||
|
||||
### 2020-06-09
|
||||
|
||||
1. 修复小程序端选中的下划线不显示问题
|
||||
2. 新增 tab 高度设置
|
||||
3. `lineHeight` 修改为只支持 `String` 方式
|
||||
|
||||
### 2020-06-11
|
||||
|
||||
1. 添加 `change` 事件
|
||||
2. 修复插件内容问题
|
||||
3. 修复下划线不居中问题
|
||||
|
||||
### 2020-06-11
|
||||
|
||||
1. 添加注释
|
||||
2. 修复 bug
|
||||
|
||||
### 2020-07-05
|
||||
|
||||
1. 新增 `padding` 的可配置
|
||||
2. 修复 `v-model` 双向绑定问题
|
||||
3. 修复初始化下划线没定位的为题
|
||||
@@ -1,241 +0,0 @@
|
||||
<template>
|
||||
<view class="v-tabs" :style="{ height: height }">
|
||||
<scroll-view class="scroll-view" :show-scrollbar="false" scroll-x scroll-with-animation :scroll-left="scrollLeft" style="width: auto; height: 100%; overflow: hidden;">
|
||||
<view class="v-tabs__inner">
|
||||
<view
|
||||
class="v-tabs__item"
|
||||
:style="{
|
||||
color: activeTab == i ? activeColor : color,
|
||||
fontSize: activeTab == i ? activeFontSize : fontSize,
|
||||
backgroundColor: activeTab == i ? backgroundColor : '',
|
||||
borderRadius,
|
||||
padding,
|
||||
|
||||
}"
|
||||
:data-index="i"
|
||||
:class="{ active: activeTab == i }"
|
||||
@tap="handleTapItem"
|
||||
v-for="(v, i) in tabs"
|
||||
:key="i"
|
||||
>
|
||||
<view class="">
|
||||
{{ v }}
|
||||
</view>
|
||||
<view class="bottomborder"></view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view
|
||||
class="v-tabs__line"
|
||||
:style="{ width: `${lineWidth}px`, height: `${lineHeight}`, backgroundColor: lineColor, transform: `translateX(${lineLeft}px)`, top: `calc(${height} - ${lineHeight})` }"
|
||||
></view> -->
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* tabs 选项卡
|
||||
* @description tabs选项卡
|
||||
* @property {String|Number} value 双向绑定的选中值
|
||||
* @property {String} height=50px 高度
|
||||
* @property {Array} tabs 选项卡列表 ['测试1', '测试2', '测试3']
|
||||
* @property {String} backgroundColor 选中背景色
|
||||
* @property {String} borderRadius 选中圆角
|
||||
* @property {String} color 默认文字的颜色
|
||||
* @property {String} activeColor 选中文字颜色
|
||||
* @property {String} fontSize 默认文字大小
|
||||
* @property {String} activeFontSize 选中文字大小
|
||||
* @property {Number} lineScale 选中标签下划线的缩放级别
|
||||
* @property {String} lineHeight 选中标签下划线的高度
|
||||
* @property {String} lineColor 选中下划线的颜色
|
||||
*
|
||||
* @event {Function(activeTab)} change 改变标签触发
|
||||
*/
|
||||
export default {
|
||||
name: 'VTabs',
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '45px'
|
||||
},
|
||||
tabs: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
},
|
||||
backgroundColor: {
|
||||
type: String,
|
||||
default: 'transparent'
|
||||
},
|
||||
borderRadius: {
|
||||
type: String,
|
||||
default: '5px'
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#333333'
|
||||
},
|
||||
activeColor: {
|
||||
type: String,
|
||||
default: '#007AFF'
|
||||
},
|
||||
fontSize: {
|
||||
type: String,
|
||||
default: '14px'
|
||||
},
|
||||
activeFontSize: {
|
||||
type: String,
|
||||
default: '14px'
|
||||
},
|
||||
padding: {
|
||||
type: String,
|
||||
default: '10rpx 20rpx'
|
||||
},
|
||||
lineScale: {
|
||||
type: Number,
|
||||
default: 0.6
|
||||
},
|
||||
lineHeight: {
|
||||
type: String,
|
||||
default: '3px'
|
||||
},
|
||||
lineColor: {
|
||||
type: String,
|
||||
default: '#007AFF'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
scrollLeft: 0,
|
||||
activeTab: 0,
|
||||
width: 0,
|
||||
lineLeft: 0,
|
||||
lineWidth: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeTab(newVal) {
|
||||
this.$emit('input', newVal * 1)
|
||||
},
|
||||
value(newVal) {
|
||||
this.activeTab = newVal
|
||||
this.getTabsWidth(0)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTapItem(e) {
|
||||
const index = e.currentTarget.dataset.index
|
||||
if (this.activeTab != index) {
|
||||
this.activeTab = index
|
||||
this.getTabsWidth(e.currentTarget.offsetLeft)
|
||||
this.$emit('change', this.activeTab)
|
||||
}
|
||||
},
|
||||
getTabsWidth(offsetLeft) {
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query
|
||||
.select('.v-tabs')
|
||||
.boundingClientRect(data => {
|
||||
this.width = data.width
|
||||
})
|
||||
.exec()
|
||||
setTimeout(() => {
|
||||
let i = 0
|
||||
let width = 0
|
||||
query
|
||||
.selectAll('.v-tabs__item')
|
||||
.boundingClientRect(data => {
|
||||
width = data.reduce((total, currentValue, currentIndex, arr) => {
|
||||
if (currentIndex < this.activeTab) {
|
||||
total = total + currentValue.width
|
||||
}
|
||||
return total
|
||||
}, 0)
|
||||
const padding = this.padding.split(' ')[0]
|
||||
const res = /(\d+)(upx|rpx|px)/.exec(padding)
|
||||
if (res && (res[2] == 'upx' || res[2] == 'rpx')) {
|
||||
width += uni.upx2px(res[1]) * 2 * this.activeTab
|
||||
} else {
|
||||
width += res[1] * this.activeTab
|
||||
}
|
||||
})
|
||||
.exec()
|
||||
query
|
||||
.select('.v-tabs__item.active')
|
||||
.boundingClientRect(data => {
|
||||
const ol = offsetLeft ? offsetLeft : width
|
||||
if (data.width) {
|
||||
this.lineLeft = ol + (data.width * (1 - this.lineScale)) / 2
|
||||
this.lineWidth = data.width * this.lineScale
|
||||
this.scrollLeft = ol - (this.width - data.width) / 2
|
||||
}
|
||||
})
|
||||
.exec()
|
||||
}, 10)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.activeTab = this.value
|
||||
this.getTabsWidth(0)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-tabs {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
border-bottom: 1rpx solid #dddddd;
|
||||
.v-tabs__inner {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
background-color: #fefefe;
|
||||
// border-bottom: 1rpx solid #dddddd;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.active{
|
||||
border-radius: 0 !important;
|
||||
.bottomborder{
|
||||
width: 42rpx;
|
||||
height: 6rpx;
|
||||
margin: 0 auto;
|
||||
background-color: #1B66FF;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
display: block !important;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
.v-tabs__item {
|
||||
// display: inline-flex;
|
||||
margin-right: 20upx;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.v-tabs__line {
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
transition: all 0.3s linear;
|
||||
border-radius: 4upx;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ ::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user