first
This commit is contained in:
8
uni_modules/xp-picker/changelog.md
Normal file
8
uni_modules/xp-picker/changelog.md
Normal file
@@ -0,0 +1,8 @@
|
||||
## 2.2.2(2022-04-27)
|
||||
更新placeholder
|
||||
## 2.2.1(2022-03-31)
|
||||
修复 app-vue3 undefined问题
|
||||
## 2.2.0(2022-03-31)
|
||||
新增v-model支持;
|
||||
新增uni-forms嵌套使用支持
|
||||
变更为uni_modules规范
|
||||
47
uni_modules/xp-picker/components/xp-picker/assert.js
Normal file
47
uni_modules/xp-picker/components/xp-picker/assert.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import {
|
||||
getLocalTime
|
||||
} from "./util.js"
|
||||
const isDev = process.env.NODE_ENV !== 'production'
|
||||
export default function(args) {
|
||||
if (isDev) {
|
||||
const {
|
||||
mode,
|
||||
yearRange
|
||||
} = args
|
||||
let val
|
||||
// #ifdef VUE2
|
||||
val = args.value
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
val = args.modelValue
|
||||
// #endif
|
||||
if ("ymdhis".indexOf(mode) === -1)
|
||||
throw new Error("illegal 'mode'")
|
||||
|
||||
if (getLocalTime(mode) == undefined)
|
||||
throw new Error("'mode' is not found")
|
||||
|
||||
if (val) {
|
||||
if (val.length !== getLocalTime(mode).length) {
|
||||
// #ifdef VUE2
|
||||
throw new Error("'value' cannot be formatted as 'mode'")
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
throw new Error("'modelValue' cannot be formatted as 'mode'")
|
||||
// #endif
|
||||
}
|
||||
const arr = val.split(/-|:|\s/)
|
||||
if (arr.length != mode.length) {
|
||||
// #ifdef VUE2
|
||||
throw new Error("'value' cannot be formatted as 'mode'")
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
throw new Error("'modelValue' cannot be formatted as 'mode'")
|
||||
// #endif
|
||||
}
|
||||
|
||||
}
|
||||
if (yearRange.length !== 2)
|
||||
throw new Error("the length of array 'year-rang' must be 2")
|
||||
}
|
||||
}
|
||||
123
uni_modules/xp-picker/components/xp-picker/util.js
Normal file
123
uni_modules/xp-picker/components/xp-picker/util.js
Normal file
@@ -0,0 +1,123 @@
|
||||
const isLeapYear = y => y % 4 == 0 && y % 100 != 0 || y % 100 == 0 && y % 400 == 0
|
||||
const variables = {
|
||||
y: {
|
||||
text: "年",
|
||||
range: [null, null]
|
||||
},
|
||||
m: {
|
||||
text: "月",
|
||||
range: [1, 12]
|
||||
},
|
||||
d: {
|
||||
text: "日",
|
||||
range: [1, 31]
|
||||
},
|
||||
h: {
|
||||
text: "时",
|
||||
range: [0, 23]
|
||||
},
|
||||
i: {
|
||||
text: "分",
|
||||
range: [0, 59]
|
||||
},
|
||||
s: {
|
||||
text: "秒",
|
||||
range: [0, 59]
|
||||
}
|
||||
}
|
||||
export function templateFactory(args) {
|
||||
const {
|
||||
mode,
|
||||
yearRange
|
||||
} = args
|
||||
let val
|
||||
// #ifdef VUE2
|
||||
val = args.value
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
val = args.modelValue
|
||||
// #endif
|
||||
const [start, end] = yearRange
|
||||
let ret = {}
|
||||
for (const key of mode) {
|
||||
ret[key] = variables[key]
|
||||
}
|
||||
if (mode.indexOf("y") !== -1) ret['y'].range = [start || 2016, end || new Date().getFullYear()]
|
||||
if (mode.indexOf("d") !== -1) {
|
||||
const date = getDate(val || getLocalTime(mode))
|
||||
ret['d'].range = [1, date]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
export function getDate(dt) {
|
||||
const s = dt.substring(0, dt.lastIndexOf("-"))
|
||||
let year, month
|
||||
const d = new Date()
|
||||
switch (s.length) {
|
||||
case 0:
|
||||
year = d.getFullYear()
|
||||
month = d.getMonth() + 1
|
||||
break;
|
||||
case 2:
|
||||
year = d.getFullYear()
|
||||
month = parseInt(s)
|
||||
break;
|
||||
default:
|
||||
const [y, m] = s.split("-")
|
||||
year = parseInt(y)
|
||||
month = parseInt(m)
|
||||
break;
|
||||
}
|
||||
const days = [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||||
return days[month - 1]
|
||||
}
|
||||
export function getLocalTime(fmt) {
|
||||
if (!fmt) return null
|
||||
const da = new Date()
|
||||
const y = fmtNumber(da.getFullYear()),
|
||||
m = fmtNumber(da.getMonth() + 1),
|
||||
d = fmtNumber(da.getDate()),
|
||||
h = fmtNumber(da.getHours()),
|
||||
i = fmtNumber(da.getMinutes()),
|
||||
s = fmtNumber(da.getSeconds())
|
||||
const types = {
|
||||
'y': `${y}`,
|
||||
'm': `${m}`,
|
||||
'd': `${d}`,
|
||||
'h': `${h}`,
|
||||
'i': `${i}`,
|
||||
's': `${s}`,
|
||||
'ym': `${y}-${m}`,
|
||||
'md': `${m}-${d}`,
|
||||
'hi': `${h}:${i}`,
|
||||
'is': `${i}:${s}`,
|
||||
'ymd': `${y}-${m}-${d}`,
|
||||
'his': `${h}:${i}:${s}`,
|
||||
'mdh': `${m}-${d} ${h}`,
|
||||
'ymdh': `${y}-${m}-${d} ${h}`,
|
||||
'mdhi': `${m}-${d} ${h}:${i}`,
|
||||
'mdhis': `${m}-${d} ${h}:${m}:${s}`,
|
||||
'yd': `${y}-${d}`,
|
||||
'ymdhi': `${y}-${m}-${d} ${h}:${i}`,
|
||||
'ymdhis': `${y}-${m}-${d} ${h}:${i}:${s}`,
|
||||
}
|
||||
return types[fmt]
|
||||
}
|
||||
export function fmtNumber(n) {
|
||||
// return n.toString().padStart(2,"0")
|
||||
return n > 9 ? n + "" : "0" + n
|
||||
}
|
||||
export function time2Timestamp(timer) {
|
||||
return new Date(timer).getTime()
|
||||
}
|
||||
|
||||
export function getForm(name = 'uniForms') {
|
||||
let parent = this.$parent;
|
||||
let parentName = parent.$options.name;
|
||||
while (parentName !== name) {
|
||||
parent = parent.$parent;
|
||||
if (!parent) return false;
|
||||
parentName = parent.$options.name;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
411
uni_modules/xp-picker/components/xp-picker/xp-picker.vue
Normal file
411
uni_modules/xp-picker/components/xp-picker/xp-picker.vue
Normal file
@@ -0,0 +1,411 @@
|
||||
<template>
|
||||
<view class="xp-h-full">
|
||||
<view @tap="show" class="xp-h-full">
|
||||
<slot>
|
||||
<view class="picker-label xp-h-full" :class="{'is-placeholder':label===placeholder}">{{label}}
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
<view class="xp-picker" :style="{'visibility':pickerVisible?'visible':'hidden'}">
|
||||
<view class="xp-picker-mask" :class="{'xp-picker-animation':animation}"
|
||||
:style="{'opacity':pickerVisible?0.6:0}" @tap="_cancel"></view>
|
||||
<view class="xp-picker-container"
|
||||
:class="{'xp-picker-container--show':pickerVisible,'xp-picker-animation':animation}">
|
||||
<view v-if="actionPosition==='top'" class="xp-picker-action">
|
||||
<view class="xp-picker-action--cancel" @tap="_cancel">取消</view>
|
||||
<view class="xp-picker-action--confirm" @tap="_confirm">确定</view>
|
||||
</view>
|
||||
<view v-if="isError" class="xp-picker-error" :style="{'height':height+'vh'}">
|
||||
<text>(请检查你的配置 或 查看控制台错误信息)</text>
|
||||
</view>
|
||||
<!-- #ifdef VUE3 -->
|
||||
<picker-view v-else style="margin-top: 40rpx;" :style="{'height':height+'vh'}"
|
||||
indicator-style="height:40px;" :value="selected" @change="_change">
|
||||
<picker-view-column v-for="(k,i) in modeArr" :key="i" class="xp-picker-column">
|
||||
<view class="xp-picker-list-item" v-for="(item,index) in cols[i]" :key="index">
|
||||
{{item+units[i]}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef VUE2 -->
|
||||
<picker-view v-else style="margin-top: 40rpx;" :style="{'height':height+'vh'}"
|
||||
indicator-style="height:40px;" :value="selected" @change="_change">
|
||||
<picker-view-column v-for="(k,i) in modeArr" :key="k" class="xp-picker-column">
|
||||
<view class="xp-picker-list-item" v-for="(item,index) in cols[i]" :key="index">
|
||||
{{item+units[i]}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<!-- #endif -->
|
||||
<view v-if="actionPosition==='bottom'" class="xp-picker-btns">
|
||||
<button class="xp-button xp-button--cancel" @tap="_cancel">取消</button>
|
||||
<button class="xp-button xp-button--confirm" @tap="_confirm">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
templateFactory,
|
||||
getLocalTime,
|
||||
fmtNumber,
|
||||
time2Timestamp,
|
||||
getDate,
|
||||
getForm
|
||||
} from "./util.js"
|
||||
import assert from './assert.js'
|
||||
export default {
|
||||
name: 'XpPicker',
|
||||
data() {
|
||||
return {
|
||||
isError: false,
|
||||
pickerVisible: false,
|
||||
cols: [],
|
||||
selected: []
|
||||
}
|
||||
},
|
||||
props: {
|
||||
mode: {
|
||||
type: String,
|
||||
default: "ymd"
|
||||
},
|
||||
animation: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
height: {
|
||||
type: [Number, String],
|
||||
default: 35
|
||||
},
|
||||
actionPosition: {
|
||||
type: String,
|
||||
default: "bottom"
|
||||
},
|
||||
yearRange: {
|
||||
type: Array,
|
||||
default: () => [2010, null]
|
||||
},
|
||||
value: String,
|
||||
// #ifdef VUE3
|
||||
modelValue: String,
|
||||
// #endif
|
||||
history: Boolean,
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
mode() {
|
||||
this.render()
|
||||
}
|
||||
},
|
||||
// #ifdef VUE3
|
||||
emits: ['confirm', 'update:modelValue'],
|
||||
// #endif
|
||||
computed: {
|
||||
modeArr() {
|
||||
return this.mode.split("")
|
||||
},
|
||||
units() {
|
||||
const arr = []
|
||||
for (const k in this.template) {
|
||||
if (this.mode.indexOf(k) !== -1) arr.push(this.template[k].text)
|
||||
}
|
||||
return arr
|
||||
},
|
||||
label() {
|
||||
const val = this.value || this.modelValue
|
||||
if (val) return val
|
||||
return this.placeholder
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.bindForm()
|
||||
|
||||
this.isConfirm = false
|
||||
this.template = {}
|
||||
this.render()
|
||||
// #ifdef VUE2
|
||||
if (this.value) {
|
||||
this.setSelected(this.value)
|
||||
}
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
if (this.modelValue) {
|
||||
this.setSelected(this.modelValue)
|
||||
}
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
bindForm() {
|
||||
this.form = getForm.call(this, 'uniForms')
|
||||
this.formItem = getForm.call(this, 'uniFormsItem')
|
||||
if (this.form && this.formItem) {
|
||||
if (this.formItem.name) {
|
||||
if (!this.is_reset) {
|
||||
this.is_reset = false
|
||||
// #ifdef VUE2
|
||||
this.formItem.setValue(this.value)
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
this.formItem.setValue(this.modelValue)
|
||||
// #endif
|
||||
}
|
||||
this.form.inputChildrens.push(this)
|
||||
}
|
||||
}
|
||||
},
|
||||
render() {
|
||||
try {
|
||||
assert(this)
|
||||
this.template = templateFactory(this) //生成所需列 默认模板
|
||||
this.initCols() //根据模板 初始化列
|
||||
this.initSelected() //设置默认值
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
this.isError = true
|
||||
}
|
||||
},
|
||||
initCols() {
|
||||
for (const k of this.mode) {
|
||||
const range = this.template[k].range
|
||||
this.fillCol(k, ...range)
|
||||
}
|
||||
},
|
||||
initSelected() {
|
||||
let dt
|
||||
// #ifdef VUE2
|
||||
dt = this.value
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
dt = this.modelValue
|
||||
// #endif
|
||||
if (!dt) dt = getLocalTime(this.mode)
|
||||
if (!dt) return
|
||||
this.setSelected(dt)
|
||||
},
|
||||
fillCol(k, s, e) {
|
||||
const index = this.mode.indexOf(k)
|
||||
let arr = []
|
||||
for (let i = s; i <= e; i++)
|
||||
arr.push(fmtNumber(i))
|
||||
// #ifdef VUE2
|
||||
this.$set(this.cols, index, arr)
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
this.cols[index] = arr
|
||||
// #endif
|
||||
},
|
||||
//dt 时间字符串 如 '2020-02-16'
|
||||
setSelected(dt) {
|
||||
const arr = dt.split(/-|:|\s/)
|
||||
const a = this.cols
|
||||
for (let i = 0; i < a.length; i++)
|
||||
this.$set(this.selected, i, a[i].indexOf(arr[i]))
|
||||
},
|
||||
show() {
|
||||
if ((!this.value && !this.modelValue) || (!this.history) || (this.history && !this.isConfirm)) {
|
||||
this.initSelected()
|
||||
}
|
||||
this.pickerVisible = true
|
||||
},
|
||||
_resolveCurrentDt() {
|
||||
let str = ""
|
||||
for (let i = 0; i < this.selected.length; i++)
|
||||
str += this.cols[i][this.selected[i]] + this.units[i]
|
||||
let dt = str
|
||||
.replace('年', '-')
|
||||
.replace('月', '-')
|
||||
.replace('日', ' ')
|
||||
.replace('时', ':')
|
||||
.replace('分', ':')
|
||||
.replace('秒', '')
|
||||
if (!this.mode.endsWith('s'))
|
||||
dt = dt.substring(0, dt.length - 1)
|
||||
return dt
|
||||
},
|
||||
_confirm() {
|
||||
const result = this._getResult()
|
||||
const val = result.value
|
||||
if (!this.isError) {
|
||||
// #ifdef VUE2
|
||||
this.$emit('input', val)
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
this.$emit('update:modelValue', val)
|
||||
// #endif
|
||||
this.$emit('confirm', result)
|
||||
this.isConfirm = true
|
||||
if (this.formItem) this.formItem.setValue(val)
|
||||
}
|
||||
this.pickerVisible = false
|
||||
},
|
||||
_getResult() {
|
||||
const value = this._resolveCurrentDt()
|
||||
const detail = {
|
||||
value
|
||||
}
|
||||
const tp = time2Timestamp(value)
|
||||
if (!isNaN(tp)) detail.timestamp = tp
|
||||
return detail
|
||||
},
|
||||
_cancel() {
|
||||
this.pickerVisible = false
|
||||
},
|
||||
_change(e) {
|
||||
let col;
|
||||
const newValue = e.detail.value
|
||||
for (let i = 0; i < newValue.length; i++) {
|
||||
if (newValue[i] !== this.selected[i]) {
|
||||
col = this.modeArr[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
this.selected = newValue
|
||||
const index = this.mode.indexOf("d")
|
||||
if (index !== -1 && (col === 'y' || col === 'm')) {
|
||||
const currentDt = this._resolveCurrentDt()
|
||||
this.fillCol("d", 1, getDate(currentDt))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.xp-h-full {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.picker-label {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.is-placeholder {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.xp-picker {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 999;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.xp-picker-container {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
transform: translateY(100%);
|
||||
z-index: 999;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
visibility: hidden;
|
||||
border-radius: 16px 16px 0 0;
|
||||
}
|
||||
|
||||
.xp-picker-container--show {
|
||||
transform: translateY(0);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.xp-picker-mask {
|
||||
z-index: 998;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
.xp-picker-animation {
|
||||
transition: all 0.25s;
|
||||
}
|
||||
|
||||
.xp-picker-error {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #ff0000
|
||||
}
|
||||
|
||||
.xp-picker-action {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 90rpx;
|
||||
padding: 0 28rpx;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
font-size: 34rpx;
|
||||
border-bottom: 0.5px solid #e5e5e5
|
||||
}
|
||||
|
||||
.xp-picker-btns {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
padding: 40rpx 30rpx;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.xp-button {
|
||||
line-height: 2.3;
|
||||
font-size: 32rpx;
|
||||
margin: 0;
|
||||
padding: 0 80rpx;
|
||||
transform: translate(0upx, 0upx);
|
||||
}
|
||||
|
||||
.xp-button:active:not([disabled]) {
|
||||
transform: translate(1upx, 1upx);
|
||||
}
|
||||
|
||||
.xp-button:after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.xp-button--cancel {
|
||||
background-color: #f5f5f5;
|
||||
color: #47a16e;
|
||||
}
|
||||
|
||||
.xp-button--confirm {
|
||||
background-color: #47a16e;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.xp-picker-action--cancel {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.xp-picker-action--confirm {
|
||||
color: #007aff;
|
||||
}
|
||||
|
||||
.xp-picker-column {
|
||||
text-align: center;
|
||||
border: none;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.xp-picker-list-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
}
|
||||
</style>
|
||||
82
uni_modules/xp-picker/package.json
Normal file
82
uni_modules/xp-picker/package.json
Normal file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"id": "xp-picker",
|
||||
"displayName": "时间选择器 xp-picker",
|
||||
"version": "2.2.2",
|
||||
"description": "一款轻量级、可配置任意列的 时间选择器组件",
|
||||
"keywords": [
|
||||
"picker",
|
||||
"time",
|
||||
"时间选择器"
|
||||
],
|
||||
"repository": "https://github.com/Pmj136/xp-picker",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "u",
|
||||
"IE": "u",
|
||||
"Edge": "u",
|
||||
"Firefox": "u",
|
||||
"Safari": "u"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
129
uni_modules/xp-picker/readme.md
Normal file
129
uni_modules/xp-picker/readme.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# xp-picker
|
||||
|
||||
###
|
||||
- 可以与uni-forms配合使用-表单验证
|
||||
- 支持vue2 vue3
|
||||
|
||||
### 一、使用示例
|
||||
#### 示例1:配合uni-forms使用,内置支持表单验证
|
||||
```html
|
||||
<template>
|
||||
<uni-forms :modelValue="form" :rules="[]">
|
||||
<uni-forms-item label="时间" name="time">
|
||||
<xp-picker v-model="form.time" />
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</template>
|
||||
```
|
||||
#### 示例2:函数式打开picker,通过 this.$refs[ref].show()
|
||||
```html
|
||||
<template>
|
||||
<view>
|
||||
<xp-picker ref="picker" @confirm="confirm" />
|
||||
<view @tap="show">开启</view>
|
||||
</view>
|
||||
</template>
|
||||
```
|
||||
```js
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
show() {
|
||||
this.$refs.picker.show()
|
||||
},
|
||||
confirm(e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
#### 示例3:xp-picker包含一个默认插槽,点击内容直接打开picker弹窗
|
||||
```html
|
||||
<template>
|
||||
<view>
|
||||
<xp-picker @confirm="confirm">打开</xp-picker>
|
||||
</view>
|
||||
</template>
|
||||
```
|
||||
```js
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
confirm(e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
### 二、属性介绍
|
||||
|
||||
| 字段 | 类型 | 必填 | 默认值 | 描述 |
|
||||
| ----------- | -------- | ---- | ---------------------- | ------------------------------- |
|
||||
| mode | String | 否 | ymd | 见下方mode 详细介绍 |
|
||||
| height | Number | 否 | 35 | 选择器的高度,单位vh |
|
||||
| animation | Boolean| 否 | true | 打开和关闭是否使用动画效果 |
|
||||
| value | String | 否 | 当前时间 | 打开选择器时默认选中的时间,详细见下方使用方式 |
|
||||
| yearRange |Array | 否 | [2016,null] | 数组第一项代表开始年份(配置为null将使用默认2016),第二项代表结束年份(配置null将使用本年),配置示例:[2010,null] |
|
||||
| history | Boolean| 否 | false | 每次打开picker时,是否保持用户最后一次选择的历史时间,若为fasle,则每次打开显示当前时间|
|
||||
| actionPosition| String|否 |bottom | 可选 top,设置"取消"和"确定"按钮的位置 |
|
||||
| ~~startRule~~ | | | | v2.0已移除 |
|
||||
| ~~endRule~~ | | | | v2.0已移除 |
|
||||
| ~~start~~ | | | | v1.2已移除 |
|
||||
| ~~end~~ | | | | v1.2已移除 |
|
||||
| ~~errorMsg~~ | | | | v1.2已移除 |
|
||||
|
||||
|
||||
### 1、mode的使用(y年;m月;d日;h时;i分;s秒)
|
||||
| 可选类型 | 描述 |
|
||||
| -------| --------------------------------- |
|
||||
| y | picker将只显示 '年'一列 |
|
||||
| ym | picker将只显示 '年月'两列 |
|
||||
| ymd | picker将只显示 '年月日'两列 |
|
||||
| ymdh | picker将只显示 '年月日时'四列 |
|
||||
| ymdhi | picker将显示 '年月日时分'五列 |
|
||||
| ymdhis | picker将显示 '年月日时分秒'六列 |
|
||||
| m | 略…… |
|
||||
| d | 略…… |
|
||||
| h | 略…… |
|
||||
| i | 略…… |
|
||||
| s | 略…… |
|
||||
| md |略…… |
|
||||
| hi | 略…… |
|
||||
| is | 略…… |
|
||||
| his | 略…… |
|
||||
| mdh | 略…… |
|
||||
| mdhi | 略…… |
|
||||
| mdhis | 略…… |
|
||||
|
||||
未出现在表格中的配置代表不支持。但是xp-picker可以适配任何自定义列,比如:其中'dh'未预定义,因此只需在源码加一行dh的预定义即可(util.js/getLocalTime),不会联系作者,热心答复
|
||||
### 2、value的使用
|
||||
此选项用于自定义picker打开时的显示时间,同样需要与mode对应
|
||||
|
||||
| mode | value格式(必须) |
|
||||
| --------- | --------------------------------- |
|
||||
| ymd | yyyy-MM-dd |
|
||||
| his | HH:mm:ss |
|
||||
| …… | …… |
|
||||
|
||||
|
||||
### 三、事件
|
||||
|
||||
| 字段 | 描述 |
|
||||
| --------- | ------------------------ |
|
||||
| confirm | 点击确定按钮的响应事件 |
|
||||
|
||||
#### confirm 事件返回属性介绍
|
||||
| 属性 | 类型 | 描述 |
|
||||
| --------- | ------------------------ |--------------------------|
|
||||
| ~~isOverTime~~ | | v2.0.0已移除|
|
||||
| value | String |选择的时间 例如:'2020-12-06'|
|
||||
| ~~resultArr~~ | |v2.1.0已移除|
|
||||
| timestamp | BigInt |返回的时间戳,支持理论可转换的时间|
|
||||
|
||||
|
||||
### 四、插槽
|
||||
可使用此方式打开picker弹窗
|
||||
Reference in New Issue
Block a user