mirror of
https://gitee.com/wot-design-uni/wot-design-uni.git
synced 2025-12-06 17:18:40 +08:00
refactor: ♻️ 重构Picker和Cell
This commit is contained in:
parent
fb7580df7e
commit
24243ca55c
@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* @Author: weisheng
|
||||||
|
* @Date: 2024-11-14 21:27:00
|
||||||
|
* @LastEditTime: 2024-11-14 22:17:54
|
||||||
|
* @LastEditors: weisheng
|
||||||
|
* @Description:
|
||||||
|
* @FilePath: /wot-design-uni/src/hooks/useColPickerData.ts
|
||||||
|
* 记得注释
|
||||||
|
*/
|
||||||
|
import type { ColPickerOption } from '@/uni_modules/wot-design-uni/components/wd-col-picker/types'
|
||||||
import { useCascaderAreaData } from '@vant/area-data'
|
import { useCascaderAreaData } from '@vant/area-data'
|
||||||
|
|
||||||
export type CascaderOption = {
|
export type CascaderOption = {
|
||||||
@ -15,7 +25,7 @@ export function useColPickerData() {
|
|||||||
const colPickerData: CascaderOption[] = useCascaderAreaData()
|
const colPickerData: CascaderOption[] = useCascaderAreaData()
|
||||||
|
|
||||||
// 根据code查找子节点,不传code则返回所有节点
|
// 根据code查找子节点,不传code则返回所有节点
|
||||||
function findChildrenByCode(data: CascaderOption[], code?: string): CascaderOption[] | null {
|
function findChildrenByCode(data: CascaderOption[], code?: string | number): CascaderOption[] | null {
|
||||||
if (!code) {
|
if (!code) {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
@ -33,5 +43,25 @@ export function useColPickerData() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return { colPickerData, findChildrenByCode }
|
function findNodeByCodeList(codeList: string[]): ColPickerOption[] {
|
||||||
|
const result: ColPickerOption[] = []
|
||||||
|
let data = colPickerData
|
||||||
|
|
||||||
|
for (const code of codeList) {
|
||||||
|
const item = data.find((item) => item.value === code)
|
||||||
|
if (item) {
|
||||||
|
result.push({
|
||||||
|
text: item.text,
|
||||||
|
value: item.value
|
||||||
|
})
|
||||||
|
data = item.children || []
|
||||||
|
} else {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
return { colPickerData, findChildrenByCode, findNodeByCodeList }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,14 +2,14 @@
|
|||||||
<page-wraper>
|
<page-wraper>
|
||||||
<wd-toast />
|
<wd-toast />
|
||||||
<demo-block title="基本用法" transparent>
|
<demo-block title="基本用法" transparent>
|
||||||
<wd-cell-group>
|
<wd-cell-group border>
|
||||||
<wd-cell title="标题文字" value="内容" />
|
<wd-cell title="标题文字" value="内容" />
|
||||||
<wd-cell title="标题文字" label="描述信息" value="内容" />
|
<wd-cell title="标题文字" label="描述信息" value="内容" />
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="图标" transparent>
|
<demo-block title="图标" transparent>
|
||||||
<wd-cell-group>
|
<wd-cell-group border>
|
||||||
<wd-cell title="标题文字" value="内容" icon="setting" />
|
<wd-cell title="标题文字" value="内容" icon="setting" />
|
||||||
<wd-cell title="标题文字" value="内容">
|
<wd-cell title="标题文字" value="内容">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
@ -20,14 +20,14 @@
|
|||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="分组标题" transparent>
|
<demo-block title="分组标题" transparent>
|
||||||
<wd-cell-group title="交易管理" value="内容">
|
<wd-cell-group border title="交易管理" value="内容">
|
||||||
<wd-cell title="标题文字" value="内容" />
|
<wd-cell title="标题文字" value="内容" />
|
||||||
<wd-cell title="标题文字" label="描述信息" value="内容"></wd-cell>
|
<wd-cell title="标题文字" label="描述信息" value="内容"></wd-cell>
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="大尺寸" transparent>
|
<demo-block title="大尺寸" transparent>
|
||||||
<wd-cell-group>
|
<wd-cell-group border>
|
||||||
<wd-cell size="large" title="标题文字" value="内容" />
|
<wd-cell size="large" title="标题文字" value="内容" />
|
||||||
<wd-cell title="标题文字" value="内容" size="large" icon="setting" is-link />
|
<wd-cell title="标题文字" value="内容" size="large" icon="setting" is-link />
|
||||||
<wd-cell size="large" title="标题文字" label="描述信息" value="内容" />
|
<wd-cell size="large" title="标题文字" label="描述信息" value="内容" />
|
||||||
@ -43,20 +43,20 @@
|
|||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="点击事件" transparent>
|
<demo-block title="点击事件" transparent>
|
||||||
<wd-cell-group>
|
<wd-cell-group border>
|
||||||
<wd-cell title="标题文字" value="内容" clickable @click="showToast" />
|
<wd-cell title="标题文字" value="内容" clickable @click="showToast" />
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="页面跳转" transparent>
|
<demo-block title="页面跳转" transparent>
|
||||||
<wd-cell-group>
|
<wd-cell-group border>
|
||||||
<wd-cell title="帮助与反馈" is-link to="/pages/index/Index" />
|
<wd-cell title="帮助与反馈" is-link to="/pages/index/Index" />
|
||||||
<wd-cell title="设置" value="内容" is-link to="/pages/button/Index" replace></wd-cell>
|
<wd-cell title="设置" value="内容" is-link to="/pages/button/Index" replace></wd-cell>
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="垂直居中" transparent>
|
<demo-block title="垂直居中" transparent>
|
||||||
<wd-cell-group>
|
<wd-cell-group border>
|
||||||
<wd-cell title="标题文字" value="内容" center />
|
<wd-cell title="标题文字" value="内容" center />
|
||||||
<wd-cell title="标题文字" label="描述信息" value="内容" center />
|
<wd-cell title="标题文字" label="描述信息" value="内容" center />
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
@ -74,13 +74,13 @@
|
|||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="设置宽度" transparent>
|
<demo-block title="设置宽度" transparent>
|
||||||
<wd-cell-group>
|
<wd-cell-group border>
|
||||||
<wd-cell title="标题文字" label="这里是文字描述这里是文字描述这里是文字描述" title-width="200px" value="内容" />
|
<wd-cell title="标题文字" label="这里是文字描述这里是文字描述这里是文字描述" title-width="200px" value="内容" />
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="自定义slot" transparent>
|
<demo-block title="自定义slot" transparent>
|
||||||
<wd-cell-group>
|
<wd-cell-group border>
|
||||||
<wd-cell title="标题文字" center>
|
<wd-cell title="标题文字" center>
|
||||||
<wd-button custom-class="custom-value" size="small" plain>按钮</wd-button>
|
<wd-button custom-class="custom-value" size="small" plain>按钮</wd-button>
|
||||||
</wd-cell>
|
</wd-cell>
|
||||||
|
|||||||
@ -1,83 +1,143 @@
|
|||||||
<template>
|
<template>
|
||||||
<page-wraper>
|
<page-wraper>
|
||||||
<wd-toast />
|
<wd-col-picker
|
||||||
|
v-model:visible="visible.visible1"
|
||||||
|
v-model="value1"
|
||||||
|
:columns="areaData1"
|
||||||
|
:column-change="columnChange1"
|
||||||
|
@confirm="(result) => handleConfirm({ ...result, index: 1 })"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<wd-col-picker
|
||||||
|
v-model:visible="visible.visible2"
|
||||||
|
v-model="value2"
|
||||||
|
:columns="areaData2"
|
||||||
|
:column-change="columnChange"
|
||||||
|
@confirm="(result) => handleConfirm({ ...result, index: 2 })"
|
||||||
|
auto-complete
|
||||||
|
/>
|
||||||
|
<wd-col-picker
|
||||||
|
v-model:visible="visible.visible3"
|
||||||
|
v-model="value4"
|
||||||
|
:columns="areaData4"
|
||||||
|
:column-change="columnChange1"
|
||||||
|
@confirm="(result) => handleConfirm({ ...result, index: 3 })"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<wd-col-picker
|
||||||
|
v-model:visible="visible.visible4"
|
||||||
|
v-model="value4"
|
||||||
|
:columns="areaData5"
|
||||||
|
:column-change="columnChange1"
|
||||||
|
@confirm="(result) => handleConfirm({ ...result, index: 4 })"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<wd-col-picker
|
||||||
|
v-model="value7"
|
||||||
|
v-model:visible="visible.visible5"
|
||||||
|
title="选择地址"
|
||||||
|
:columns="areaData1"
|
||||||
|
:column-change="columnChange1"
|
||||||
|
@confirm="(result) => handleConfirm({ ...result, index: 5 })"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<wd-col-picker
|
||||||
|
v-model:visible="visible.visible6"
|
||||||
|
v-model="value8"
|
||||||
|
:columns="areaData1"
|
||||||
|
:column-change="columnChange1"
|
||||||
|
:before-confirm="beforeConfirm"
|
||||||
|
@confirm="(result) => handleConfirm({ ...result, index: 6 })"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<wd-col-picker
|
||||||
|
label="选择地址"
|
||||||
|
v-model="value11"
|
||||||
|
v-model:visible="visible.visible7"
|
||||||
|
:columns="areaData1"
|
||||||
|
@confirm="(result) => handleConfirm({ ...result, index: 7 })"
|
||||||
|
:column-change="columnChange2"
|
||||||
|
/>
|
||||||
|
|
||||||
<view style="margin: 20px 0">
|
<view style="margin: 20px 0">
|
||||||
<wd-cell-group border>
|
<wd-cell-group border>
|
||||||
<wd-col-picker label="选择地址" v-model="value1" :columns="areaData1" :column-change="columnChange1" @confirm="handleValue" />
|
<wd-cell title="选择地址" :value="cellValue.value1" is-link @click="visible.visible1 = true"></wd-cell>
|
||||||
<wd-col-picker label="初始选项" v-model="value2" :columns="areaData2" :column-change="columnChange" auto-complete />
|
<wd-cell title="初始选项" :value="cellValue.value2" is-link @click="visible.visible2 = true"></wd-cell>
|
||||||
<wd-col-picker label="禁用" disabled v-model="value3" :columns="areaData3" :column-change="columnChange1" />
|
<wd-cell title="禁用选项" :value="cellValue.value3" is-link @click="visible.visible3 = true"></wd-cell>
|
||||||
<wd-col-picker label="只读" readonly v-model="value3" :columns="areaData3" :column-change="columnChange1" />
|
<wd-cell title="选项提示信息" :value="cellValue.value4" is-link @click="visible.visible4 = true"></wd-cell>
|
||||||
<wd-col-picker label="禁用选项" v-model="value4" :columns="areaData4" :column-change="columnChange1" />
|
<wd-cell title="自定义标题" :value="cellValue.value5" is-link @click="visible.visible5 = true"></wd-cell>
|
||||||
<wd-col-picker label="选项提示信息" v-model="value5" :columns="areaData5" :column-change="columnChange1" />
|
<wd-cell title="before-confirm" :value="cellValue.value6" is-link @click="visible.visible6 = true"></wd-cell>
|
||||||
<wd-col-picker label="展示格式化" v-model="value6" :columns="areaData3" :column-change="columnChange1" :display-format="displayFormat" />
|
<wd-cell title="加载动画" :value="cellValue.value7" is-link @click="visible.visible7 = true"></wd-cell>
|
||||||
<wd-col-picker label="标题" v-model="value7" title="选择地址" :columns="areaData1" :column-change="columnChange1" />
|
|
||||||
<wd-col-picker label="before-confirm" v-model="value8" :columns="areaData1" :column-change="columnChange1" :before-confirm="beforeConfirm" />
|
|
||||||
<wd-col-picker label="错误" error v-model="value9" :columns="areaData1" :column-change="columnChange1" />
|
|
||||||
<wd-col-picker label="必填" required v-model="value10" :columns="areaData1" :column-change="columnChange1" />
|
|
||||||
</wd-cell-group>
|
</wd-cell-group>
|
||||||
</view>
|
</view>
|
||||||
<demo-block title="一般column-change是个异步获取数据的操作,触发column-change组件会有默认loading,数据响应后关闭loading" transparent>
|
<wd-toast />
|
||||||
<wd-col-picker label="选择地址" v-model="value11" :columns="areaData1" :column-change="columnChange2" />
|
|
||||||
</demo-block>
|
|
||||||
<demo-block title="label不传" transparent>
|
|
||||||
<wd-col-picker v-model="value12" :columns="areaData1" :column-change="columnChange1" />
|
|
||||||
</demo-block>
|
|
||||||
<demo-block title="大小" transparent>
|
|
||||||
<wd-col-picker label="选择地址" v-model="value13" size="large" :columns="areaData1" :column-change="columnChange1" />
|
|
||||||
</demo-block>
|
|
||||||
<demo-block title="值靠右展示" transparent>
|
|
||||||
<wd-col-picker label="选择地址" align-right v-model="value14" :columns="areaData1" :column-change="columnChange1" />
|
|
||||||
</demo-block>
|
|
||||||
<demo-block title="自定义选择器" transparent>
|
|
||||||
<view style="margin-left: 15px">
|
|
||||||
<view style="margin-bottom: 10px">当前选中项: {{ displayValue }}</view>
|
|
||||||
<wd-col-picker
|
|
||||||
v-model="value15"
|
|
||||||
use-default-slot
|
|
||||||
:columns="areaData1"
|
|
||||||
:column-change="columnChange1"
|
|
||||||
style="display: inline-block"
|
|
||||||
@confirm="handleConfirm"
|
|
||||||
>
|
|
||||||
<wd-button>选择地址</wd-button>
|
|
||||||
</wd-col-picker>
|
|
||||||
</view>
|
|
||||||
</demo-block>
|
|
||||||
</page-wraper>
|
</page-wraper>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, reactive, ref } from 'vue'
|
||||||
import { useToast } from '@/uni_modules/wot-design-uni'
|
import { useToast } from '@/uni_modules/wot-design-uni'
|
||||||
import type { ColPickerColumnChange } from '@/uni_modules/wot-design-uni/components/wd-col-picker/types'
|
import type { ColPickerColumnChange, ColPickerOption } from '@/uni_modules/wot-design-uni/components/wd-col-picker/types'
|
||||||
import { useColPickerData } from '@/hooks/useColPickerData'
|
import { useColPickerData } from '@/hooks/useColPickerData'
|
||||||
|
|
||||||
const { colPickerData, findChildrenByCode } = useColPickerData()
|
const { colPickerData, findChildrenByCode, findNodeByCodeList } = useColPickerData()
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
toast.loading('数据加载中')
|
|
||||||
await sleep()
|
await sleep()
|
||||||
toast.close()
|
|
||||||
value2.value = ['150000', '150100', '150121']
|
value2.value = ['150000', '150100', '150121']
|
||||||
|
const result = findNodeByCodeList(value2.value)
|
||||||
|
cellValue.value2 = result.map((item) => item.text).join('/')
|
||||||
})
|
})
|
||||||
|
|
||||||
const value1 = ref<any[]>([])
|
const visible = reactive({
|
||||||
|
visible1: false,
|
||||||
|
visible2: false,
|
||||||
|
visible3: false,
|
||||||
|
visible4: false,
|
||||||
|
visible5: false,
|
||||||
|
visible6: false,
|
||||||
|
visible7: false,
|
||||||
|
visible8: false,
|
||||||
|
visible9: false,
|
||||||
|
visible10: false,
|
||||||
|
visible11: false,
|
||||||
|
visible12: false,
|
||||||
|
visible13: false,
|
||||||
|
visible14: false,
|
||||||
|
visible15: false
|
||||||
|
})
|
||||||
|
|
||||||
|
const cellValue = reactive<{ [key: PropertyKey]: any }>({
|
||||||
|
value1: '',
|
||||||
|
value2: '',
|
||||||
|
value3: '',
|
||||||
|
value4: '',
|
||||||
|
value5: '',
|
||||||
|
value6: '',
|
||||||
|
value7: '',
|
||||||
|
value8: '',
|
||||||
|
value9: '',
|
||||||
|
value10: '',
|
||||||
|
value11: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const value1 = ref<string[]>([])
|
||||||
const value2 = ref<string[]>([])
|
const value2 = ref<string[]>([])
|
||||||
const value3 = ref<any[]>(['130000', '130200', '130204'])
|
const value3 = ref<string[]>(['130000', '130200', '130204'])
|
||||||
const value4 = ref<any[]>([])
|
const value4 = ref<string[]>([])
|
||||||
const value5 = ref<any[]>([])
|
const value5 = ref<string[]>([])
|
||||||
const value6 = ref<any[]>(['130000', '130200', '130204'])
|
const value6 = ref<string[]>(['130000', '130200', '130204'])
|
||||||
const value7 = ref<any[]>([])
|
const value7 = ref<string[]>([])
|
||||||
const value8 = ref<any[]>([])
|
const value8 = ref<string[]>([])
|
||||||
const value9 = ref<any[]>([])
|
const value9 = ref<string[]>([])
|
||||||
const value10 = ref<any[]>([])
|
const value10 = ref<string[]>([])
|
||||||
const value11 = ref<any[]>([])
|
const value11 = ref<string[]>([])
|
||||||
const value12 = ref<any[]>([])
|
const value12 = ref<string[]>([])
|
||||||
const value13 = ref<any[]>([])
|
const value13 = ref<string[]>([])
|
||||||
const value14 = ref<any[]>([])
|
const value14 = ref<string[]>([])
|
||||||
const value15 = ref<any[]>([])
|
const value15 = ref<string[]>([])
|
||||||
const displayValue = ref<string>('')
|
const displayValue = ref<string>('')
|
||||||
const areaData1 = ref<any[]>([
|
const areaData1 = ref<ColPickerOption[][]>([
|
||||||
colPickerData.map((item) => {
|
colPickerData.map((item) => {
|
||||||
return {
|
return {
|
||||||
value: item.value,
|
value: item.value,
|
||||||
@ -86,8 +146,8 @@ const areaData1 = ref<any[]>([
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
|
||||||
const areaData2 = ref<any[]>([])
|
const areaData2 = ref<ColPickerOption[][]>([])
|
||||||
const areaData3 = ref<any[]>([
|
const areaData3 = ref<ColPickerOption[][]>([
|
||||||
colPickerData.map((item) => {
|
colPickerData.map((item) => {
|
||||||
return {
|
return {
|
||||||
value: item.value,
|
value: item.value,
|
||||||
@ -107,7 +167,7 @@ const areaData3 = ref<any[]>([
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
const areaData4 = ref<any[]>([
|
const areaData4 = ref<ColPickerOption[][]>([
|
||||||
colPickerData.map((item) => {
|
colPickerData.map((item) => {
|
||||||
return {
|
return {
|
||||||
value: item.value,
|
value: item.value,
|
||||||
@ -143,7 +203,7 @@ const columnChange1: ColPickerColumnChange = ({ selectedItem, resolve, finish })
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const columnChange: ColPickerColumnChange = async ({ selectedItem, resolve, finish }) => {
|
const columnChange: ColPickerColumnChange = async ({ selectedItem, index, resolve, finish }) => {
|
||||||
await sleep(0.3)
|
await sleep(0.3)
|
||||||
const areaData = findChildrenByCode(colPickerData, selectedItem.value)
|
const areaData = findChildrenByCode(colPickerData, selectedItem.value)
|
||||||
if (areaData && areaData.length) {
|
if (areaData && areaData.length) {
|
||||||
@ -182,10 +242,10 @@ const columnChange2: ColPickerColumnChange = ({ selectedItem, resolve, finish })
|
|||||||
}
|
}
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
const displayFormat = (selectedItems: Record<string, any>[]) => {
|
const displayFormat = (selectedItems: ColPickerOption[]) => {
|
||||||
return selectedItems[selectedItems.length - 2].label + '-' + selectedItems[selectedItems.length - 1].label
|
return selectedItems[selectedItems.length - 2].label + '-' + selectedItems[selectedItems.length - 1].label
|
||||||
}
|
}
|
||||||
const beforeConfirm = (value: (string | number)[], selectedItems: Record<string, any>[], resolve: (isPass: boolean) => void) => {
|
const beforeConfirm = (value: (string | number)[], selectedItems: ColPickerOption[], resolve: (isPass: boolean) => void) => {
|
||||||
if (parseInt(String(value[2])) > 120000) {
|
if (parseInt(String(value[2])) > 120000) {
|
||||||
toast.error('该地区库存不足')
|
toast.error('该地区库存不足')
|
||||||
resolve(false)
|
resolve(false)
|
||||||
@ -202,15 +262,12 @@ function sleep(second: number = 1) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleConfirm({ selectedItems }: any) {
|
function handleConfirm({ selectedItems, index }: { selectedItems: ColPickerOption[]; index: number }) {
|
||||||
displayValue.value = selectedItems
|
cellValue[`value${index}`] = selectedItems
|
||||||
.map((item: any) => {
|
.map((item) => {
|
||||||
return item.label
|
return item.label
|
||||||
})
|
})
|
||||||
.join('')
|
.join('/')
|
||||||
}
|
|
||||||
function handleValue({ value }: any) {
|
|
||||||
console.log(value)
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
<demo-block title="进度条状态">
|
<demo-block title="进度条状态">
|
||||||
<wd-progress :percentage="100" hide-text status="success" />
|
<wd-progress :percentage="100" hide-text status="success" />
|
||||||
<wd-progress :percentage="80" hide-text status="danger" />
|
<wd-progress :percentage="80" hide-text status="danger" />
|
||||||
|
<wd-progress :percentage="90" hide-text status="warning" />
|
||||||
</demo-block>
|
</demo-block>
|
||||||
|
|
||||||
<demo-block title="修改颜色">
|
<demo-block title="修改颜色">
|
||||||
@ -24,9 +25,10 @@
|
|||||||
</page-wraper>
|
</page-wraper>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { ProgressColor } from '@/uni_modules/wot-design-uni/components/wd-progress/types'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const colorObject = ref<any>([
|
const colorObject = ref<ProgressColor[]>([
|
||||||
{
|
{
|
||||||
color: 'yellow',
|
color: 'yellow',
|
||||||
percentage: 30
|
percentage: 30
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
* 辅助函数
|
* 辅助函数
|
||||||
*/
|
*/
|
||||||
@import 'config';
|
@import 'config';
|
||||||
$default-theme: #4d80f0 !default; // 正常色
|
|
||||||
|
|
||||||
/* 转换成字符串 */
|
/* 转换成字符串 */
|
||||||
@function selectorToString($selector) {
|
@function selectorToString($selector) {
|
||||||
@ -36,54 +35,4 @@ $default-theme: #4d80f0 !default; // 正常色
|
|||||||
@else {
|
@else {
|
||||||
@return false;
|
@return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主题色切换
|
|
||||||
* @params $theme-color 主题色
|
|
||||||
* @params $type 变暗’dark‘ 变亮 'light'
|
|
||||||
* @params $mix-color 自己设置的混色
|
|
||||||
*/
|
|
||||||
@function themeColor($theme-color, $type: "", $mix-color: "") {
|
|
||||||
@if $default-theme !=#4d80f0 {
|
|
||||||
@if $type=="dark" {
|
|
||||||
@return darken($theme-color, 10%);
|
|
||||||
}
|
|
||||||
|
|
||||||
@else if $type=="light" {
|
|
||||||
@return lighten($theme-color, 10%);
|
|
||||||
}
|
|
||||||
|
|
||||||
@else {
|
|
||||||
@return $theme-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@else {
|
|
||||||
@return $mix-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 颜色结果切换, 如果开启线性渐变色 使用渐变色,如果没有开启,那么使用主题色
|
|
||||||
* @params $open-linear 是否开启线性渐变色
|
|
||||||
* @params $deg 渐变色角度
|
|
||||||
* @params $theme-color 当前配色
|
|
||||||
* @params [Array] $set 主题色明暗设置,与 $color-list 数量对应
|
|
||||||
* @params [Array] $color-list 渐变色顺序, $color-list 和 $per-list 数量相同
|
|
||||||
* @params [Array] $per-list 渐变色比例
|
|
||||||
*/
|
|
||||||
@function resultColor($deg, $theme-color, $set, $color-list, $per-list) {
|
|
||||||
// 开启渐变
|
|
||||||
|
|
||||||
$len: length($color-list);
|
|
||||||
$arg: $deg;
|
|
||||||
|
|
||||||
@for $i from 1 through $len {
|
|
||||||
$arg: $arg + ","+ themeColor($theme-color, nth($set, $i), nth($color-list, $i)) + " "+ nth($per-list, $i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@return linear-gradient(unquote($arg));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -5,9 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
/*----------------------------------------- Theme color. start ----------------------------------------*/
|
/*----------------------------------------- Theme color. start ----------------------------------------*/
|
||||||
/* 主题颜色 */
|
/* 主题颜色 */
|
||||||
$-color-theme: var(--wot-color-theme, $default-theme) !default; // 主题色
|
$-color-theme: var(--wot-color-theme, #4d80f0) !default; // 主题色
|
||||||
$-color-white: var(--wot-color-white, rgb(255, 255, 255)) !default; // 用于mix的白色
|
$-color-white: var(--wot-color-white, #ffffff) !default; // 白色
|
||||||
$-color-black: var(--wot-color-black, rgb(0, 0, 0)) !default; // 用于mix的黑色
|
$-color-black: var(--wot-color-black, #000000) !default; // 黑色
|
||||||
|
|
||||||
/* 辅助色 */
|
/* 辅助色 */
|
||||||
$-color-success: var(--wot-color-success, #34d19d) !default; // 成功色
|
$-color-success: var(--wot-color-success, #34d19d) !default; // 成功色
|
||||||
@ -170,19 +170,17 @@ $-button-error-bg-color: var(--wot-button-error-bg-color, $-color-danger) !defau
|
|||||||
$-button-text-hover-opacity: var(--wot-button-text-hover-opacity, 0.7) !default; // 文字button激活时透明度
|
$-button-text-hover-opacity: var(--wot-button-text-hover-opacity, 0.7) !default; // 文字button激活时透明度
|
||||||
|
|
||||||
/* cell */
|
/* cell */
|
||||||
$-cell-padding: var(--wot-cell-padding, $-size-side-padding) !default; // cell 左右padding距离
|
$-cell-vertical-padding: var(--wot-cell-vertical-padding, $-size-side-padding) !default; // cell 左右padding距离
|
||||||
$-cell-line-height: var(--wot-cell-line-height, 24px) !default; // 行高
|
$-cell-horizontal-padding: var(--wot-cell-horizontal-padding, 10px) !default; // cell 上下padding
|
||||||
|
$-cell-horizontal-padding-large: var(--wot-cell-horizontal-padding-large, 12px) !default; // large类型cell上下padding
|
||||||
|
$-cell-horizontal-padding-with-label: var(--wot-cell-wrapper-padding-with-label, 16px) !default; // cell 上下padding(有label情况下)
|
||||||
|
|
||||||
|
$-cell-line-height: var(--wot-cell-line-height, 24px) !default; // 行高
|
||||||
$-cell-group-title-fs: var(--wot-cell-group-title-fs, $-fs-title) !default; // 组标题字号
|
$-cell-group-title-fs: var(--wot-cell-group-title-fs, $-fs-title) !default; // 组标题字号
|
||||||
$-cell-group-padding: var(--wot-cell-group-padding, 13px $-cell-padding) !default; // 组padding
|
$-cell-group-padding: var(--wot-cell-group-padding, 13px $-cell-vertical-padding) !default; // 组padding
|
||||||
$-cell-group-title-color: var(--wot-cell-group-title-color, rgba(0, 0, 0, 0.85)) !default; // 组标题文字颜色
|
$-cell-group-title-color: var(--wot-cell-group-title-color, rgba(0, 0, 0, 0.85)) !default; // 组标题文字颜色
|
||||||
$-cell-group-value-fs: var(--wot-cell-group-value-fs, $-fs-content) !default; // 组值字号
|
$-cell-group-value-fs: var(--wot-cell-group-value-fs, $-fs-content) !default; // 组值字号
|
||||||
$-cell-group-value-color: var(--wot-cell-group-value-color, $-color-content) !default; // 组值文字颜色
|
$-cell-group-value-color: var(--wot-cell-group-value-color, $-color-content) !default; // 组值文字颜色
|
||||||
|
|
||||||
$-cell-wrapper-padding: var(--wot-cell-wrapper-padding, 10px) !default; // cell 容器padding
|
|
||||||
$-cell-wrapper-padding-large: var(--wot-cell-wrapper-padding-large, 12px) !default; // large类型cell容器padding
|
|
||||||
|
|
||||||
$-cell-wrapper-padding-with-label: var(--wot-cell-wrapper-padding-with-label, 16px) !default; // cell 容器上下padding(有label情况下)
|
|
||||||
$-cell-icon-right: var(--wot-cell-icon-right, 4px) !default; // 图标距离右边缘
|
$-cell-icon-right: var(--wot-cell-icon-right, 4px) !default; // 图标距离右边缘
|
||||||
$-cell-icon-size: var(--wot-cell-icon-size, 16px) !default; // 图标大小
|
$-cell-icon-size: var(--wot-cell-icon-size, 16px) !default; // 图标大小
|
||||||
$-cell-title-fs: var(--wot-cell-title-fs, 14px) !default; // 标题字号
|
$-cell-title-fs: var(--wot-cell-title-fs, 14px) !default; // 标题字号
|
||||||
@ -457,10 +455,7 @@ $-col-picker-selected-color: var(--wot-col-picker-selected-color, rgba(0, 0, 0,
|
|||||||
$-col-picker-selected-fw: var(--wot-col-picker-selected-fw, 700) !default; // 弹框顶部值高亮字重
|
$-col-picker-selected-fw: var(--wot-col-picker-selected-fw, 700) !default; // 弹框顶部值高亮字重
|
||||||
$-col-picker-line-width: var(--wot-col-picker-line-width, 16px) !default; // 弹框顶部值高亮线条宽度
|
$-col-picker-line-width: var(--wot-col-picker-line-width, 16px) !default; // 弹框顶部值高亮线条宽度
|
||||||
$-col-picker-line-height: var(--wot-col-picker-line-height, 3px) !default; // 弹框顶部值高亮线条高度
|
$-col-picker-line-height: var(--wot-col-picker-line-height, 3px) !default; // 弹框顶部值高亮线条高度
|
||||||
$-col-picker-line-color: var(
|
$-col-picker-line-color: var(--wot-col-picker-line-color,linear-gradient(315deg, rgba(81, 124, 240, 1), rgba(118, 158, 245, 1))) !default; // 弹框顶部值高亮线条颜色
|
||||||
--wot-col-picker-line-color,
|
|
||||||
linear-gradient(315deg, rgba(81, 124, 240, 1), rgba(118, 158, 245, 1))
|
|
||||||
) !default; // 弹框顶部值高亮线条颜色
|
|
||||||
$-col-picker-line-box-shadow: var(--wot-col-picker-line-box-shadow, 0px 1px 2px 0px rgba(1, 87, 255, 0.2)) !default; // 弹框顶部值高亮线条阴影
|
$-col-picker-line-box-shadow: var(--wot-col-picker-line-box-shadow, 0px 1px 2px 0px rgba(1, 87, 255, 0.2)) !default; // 弹框顶部值高亮线条阴影
|
||||||
$-col-picker-list-height: var(--wot-col-picker-list-height, 53vh) !default; // 弹框列表高度
|
$-col-picker-list-height: var(--wot-col-picker-list-height, 53vh) !default; // 弹框列表高度
|
||||||
$-col-picker-list-padding-bottom: var(--wot-col-picker-list-padding-bottom, 30px) !default; // 弹框列表底部间距
|
$-col-picker-list-padding-bottom: var(--wot-col-picker-list-padding-bottom, 30px) !default; // 弹框列表底部间距
|
||||||
@ -486,15 +481,9 @@ $-progress-padding: var(--wot-progress-padding, 9px 0 8px) !default; // 进度
|
|||||||
$-progress-bg: var(--wot-progress-bg, rgba(229, 229, 229, 1)) !default; // 进度条底色
|
$-progress-bg: var(--wot-progress-bg, rgba(229, 229, 229, 1)) !default; // 进度条底色
|
||||||
$-progress-danger-color: var(--wot-progress-danger-color, $-color-danger) !default; // 进度条danger颜色
|
$-progress-danger-color: var(--wot-progress-danger-color, $-color-danger) !default; // 进度条danger颜色
|
||||||
$-progress-success-color: var(--wot-progress-success-color, $-color-success) !default; // 进度条success进度条颜色
|
$-progress-success-color: var(--wot-progress-success-color, $-color-success) !default; // 进度条success进度条颜色
|
||||||
$-progress-color: var(--wot-progress-color, resultColor(315deg, $-color-theme, 'dark' 'light', #517cf0 #769ef5, 0% 100%)) !default; // 进度条渐变色
|
$-progress-warning-color: var(--wot-progress-warning-color, $-color-warning) !default; // 进度条warning进度条颜色
|
||||||
$-progress-linear-success-color: var(
|
|
||||||
--wot-progress-linear-success-color,
|
$-progress-color: var(--wot-progress-color, $-color-success) !default; // 进度条颜色
|
||||||
resultColor(315deg, $-color-theme, 'dark' 'light', #20b080 #2bd69d, 0% 100%)
|
|
||||||
) !default; // success进度条渐变色
|
|
||||||
$-progress-linear-danger-color: var(
|
|
||||||
--wot-progress-linear-danger-color,
|
|
||||||
resultColor(315deg, $-color-theme, 'dark' 'light', #e04350 #ff5964, 0% 100%)
|
|
||||||
) !default; // danger进度条渐变色
|
|
||||||
$-progress-height: var(--wot-progress-height, 3px) !default; // 进度条高度
|
$-progress-height: var(--wot-progress-height, 3px) !default; // 进度条高度
|
||||||
$-progress-label-color: var(--wot-progress-label-color, #333) !default; // 文字颜色
|
$-progress-label-color: var(--wot-progress-label-color, #333) !default; // 文字颜色
|
||||||
$-progress-label-fs: var(--wot-progress-label-fs, 14px) !default; // 文字字号
|
$-progress-label-fs: var(--wot-progress-label-fs, 14px) !default; // 文字字号
|
||||||
@ -552,14 +541,11 @@ $-search-light-bg: var(--wot-search-light-bg, $-color-bg) !default; // light 类
|
|||||||
/* slider */
|
/* slider */
|
||||||
$-slider-fs: var(--wot-slider-fs, $-fs-content) !default; // 字体大小
|
$-slider-fs: var(--wot-slider-fs, $-fs-content) !default; // 字体大小
|
||||||
$-slider-handle-radius: var(--wot-slider-handle-radius, 12px) !default; // 滑块半径
|
$-slider-handle-radius: var(--wot-slider-handle-radius, 12px) !default; // 滑块半径
|
||||||
$-slider-handle-bg: var(--wot-slider-handle-bg, resultColor(139deg, $-color-theme, 'dark' 'light', #ffffff #f7f7f7, 0% 100%)) !default; // 滑块背景
|
$-slider-handle-bg: var(--wot-slider-handle-bg, $-color-white) !default; // 滑块背景
|
||||||
$-slider-axie-height: var(--wot-slider-axie-height, 3px) !default; // 滑轴高度
|
$-slider-axie-height: var(--wot-slider-axie-height, 3px) !default; // 滑轴高度
|
||||||
$-slider-color: var(--wot-slider-color, #333) !default; // 字体颜色
|
$-slider-color: var(--wot-slider-color, #333) !default; // 字体颜色
|
||||||
$-slider-axie-bg: var(--wot-slider-axie-bg, #e5e5e5) !default; // 滑轴的默认背景色
|
$-slider-axie-bg: var(--wot-slider-axie-bg, #e5e5e5) !default; // 滑轴的默认背景色
|
||||||
$-slider-line-color: var(
|
$-slider-line-color: var(--wot-slider-line-color, $-color-theme) !default; // 进度条颜色
|
||||||
--wot-slider-line-color,
|
|
||||||
resultColor(315deg, $-color-theme, 'dark' 'light', #517cf0 #769ef5, 0% 100%)
|
|
||||||
) !default; // 进度条颜色
|
|
||||||
$-slider-disabled-color: var(--wot-slider-disabled-color, rgba(0, 0, 0, 0.25)) !default; // 禁用状态下字体颜色
|
$-slider-disabled-color: var(--wot-slider-disabled-color, rgba(0, 0, 0, 0.25)) !default; // 禁用状态下字体颜色
|
||||||
|
|
||||||
/* sort-button */
|
/* sort-button */
|
||||||
@ -628,7 +614,7 @@ $-tag-primary-color: var(--wot-tag-primary-color, $-color-theme) !default; //
|
|||||||
$-tag-danger-color: var(--wot-tag-danger-color, $-color-danger) !default; // danger 颜色
|
$-tag-danger-color: var(--wot-tag-danger-color, $-color-danger) !default; // danger 颜色
|
||||||
$-tag-warning-color: var(--wot-tag-warning-color, $-color-warning) !default; // warning 颜色
|
$-tag-warning-color: var(--wot-tag-warning-color, $-color-warning) !default; // warning 颜色
|
||||||
$-tag-success-color: var(--wot-tag-success-color, $-color-success) !default; // success 颜色
|
$-tag-success-color: var(--wot-tag-success-color, $-color-success) !default; // success 颜色
|
||||||
$-tag-info-bg: var(--wot-tag-info-bg, resultColor(49deg, $-color-black, 'dark' 'light', #808080 #999999, 0% 100%)) !default; // info 背景颜色
|
$-tag-info-bg: var(--wot-tag-info-bg, linear-gradient(49deg, #808080 0%, #999999 100%)) !default; // info 背景颜色
|
||||||
$-tag-primary-bg: var(--wot-tag-primary-bg, $-color-theme) !default; // 主背景颜色
|
$-tag-primary-bg: var(--wot-tag-primary-bg, $-color-theme) !default; // 主背景颜色
|
||||||
$-tag-danger-bg: var(--wot-tag-danger-bg, $-color-danger) !default; // danger 背景颜色
|
$-tag-danger-bg: var(--wot-tag-danger-bg, $-color-danger) !default; // danger 背景颜色
|
||||||
$-tag-warning-bg: var(--wot-tag-warning-bg, $-color-warning) !default; // warning 背景颜色
|
$-tag-warning-bg: var(--wot-tag-warning-bg, $-color-warning) !default; // warning 背景颜色
|
||||||
@ -763,7 +749,7 @@ $-circle-text-color: var(--wot-circle-text-color, $-color-content) !default; //
|
|||||||
/* swiper */
|
/* swiper */
|
||||||
$-swiper-radius: var(--wot-swiper-radius, 8px);
|
$-swiper-radius: var(--wot-swiper-radius, 8px);
|
||||||
$-swiper-item-padding: var(--wot-swiper-item-padding, 0);
|
$-swiper-item-padding: var(--wot-swiper-item-padding, 0);
|
||||||
$-swiper-item-text-color: var(--wot-swiper-item-text-color, #ffffff);
|
$-swiper-item-text-color: var(--wot-swiper-item-text-color, $-color-white);
|
||||||
$-swiper-item-text-fs: var(--wot-swiper-item-text-fs, $-fs-title);
|
$-swiper-item-text-fs: var(--wot-swiper-item-text-fs, $-fs-title);
|
||||||
|
|
||||||
|
|
||||||
@ -787,7 +773,7 @@ $-swiper-nav-btn-size: var(--wot-swiper-nav-btn-size, 48rpx) !default;
|
|||||||
$-segmented-padding: var(--wot-segmented-padding, 4px) !default; // 分段器padding
|
$-segmented-padding: var(--wot-segmented-padding, 4px) !default; // 分段器padding
|
||||||
$-segmented-item-bg-color: var(--wot-segmented-item-bg-color, #eeeeee) !default;
|
$-segmented-item-bg-color: var(--wot-segmented-item-bg-color, #eeeeee) !default;
|
||||||
$-segmented-item-color: var(--wot-segmented-item-color, rgba(0, 0, 0, 0.85)) !default; // 标题文字颜色
|
$-segmented-item-color: var(--wot-segmented-item-color, rgba(0, 0, 0, 0.85)) !default; // 标题文字颜色
|
||||||
$-segmented-item-acitve-bg: var(--wot-segmented-item-acitve-bg, #ffffff) !default; // 标题文字颜色
|
$-segmented-item-acitve-bg: var(--wot-segmented-item-acitve-bg, $-color-white) !default; // 标题文字颜色
|
||||||
$-segmented-item-disabled-color: var(--wot-segmented-item-disabled-color, rgba(0, 0, 0, 0.25)) !default; // 标题文字禁用颜色
|
$-segmented-item-disabled-color: var(--wot-segmented-item-disabled-color, rgba(0, 0, 0, 0.25)) !default; // 标题文字禁用颜色
|
||||||
|
|
||||||
/* tabbar */
|
/* tabbar */
|
||||||
@ -827,7 +813,7 @@ $-navbar-capsule-icon-size: var(--wot-navbar-capsule-icon-size, 20px) !default;
|
|||||||
|
|
||||||
/* table */
|
/* table */
|
||||||
$-table-color: var(--wot-table-color, $-font-gray-1) !default; // 表格字体颜色
|
$-table-color: var(--wot-table-color, $-font-gray-1) !default; // 表格字体颜色
|
||||||
$-table-bg: var(--wot-table-bg, #ffffff) !default; // 表格背景颜色
|
$-table-bg: var(--wot-table-bg, $-color-white) !default; // 表格背景颜色
|
||||||
$-table-stripe-bg: var(--wot-table-stripe-bg, #f3f3f3) !default; // 表格背景颜色
|
$-table-stripe-bg: var(--wot-table-stripe-bg, #f3f3f3) !default; // 表格背景颜色
|
||||||
$-table-border-color: var(--wot-table-border-color, #ececec) !default; // 表格边框颜色
|
$-table-border-color: var(--wot-table-border-color, #ececec) !default; // 表格边框颜色
|
||||||
$-table-font-size: var(--wot-table-font-size, 13px) !default; // 表格字体大小
|
$-table-font-size: var(--wot-table-font-size, 13px) !default; // 表格字体大小
|
||||||
|
|||||||
@ -115,7 +115,13 @@ export const actionSheetProps = {
|
|||||||
* @default true
|
* @default true
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
safeAreaInsetBottom: makeBooleanProp(true)
|
safeAreaInsetBottom: makeBooleanProp(true),
|
||||||
|
/**
|
||||||
|
* 是否当关闭时将弹出层隐藏(display: none)
|
||||||
|
* 类型:boolean
|
||||||
|
* 默认值:true
|
||||||
|
*/
|
||||||
|
hideWhenClose: makeBooleanProp(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ActionSheetProps = ExtractPropTypes<typeof actionSheetProps>
|
export type ActionSheetProps = ExtractPropTypes<typeof actionSheetProps>
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
:close-on-click-modal="closeOnClickModal"
|
:close-on-click-modal="closeOnClickModal"
|
||||||
:safe-area-inset-bottom="safeAreaInsetBottom"
|
:safe-area-inset-bottom="safeAreaInsetBottom"
|
||||||
:lazy-render="lazyRender"
|
:lazy-render="lazyRender"
|
||||||
|
:hideWhenClose="hideWhenClose"
|
||||||
@enter="handleOpen"
|
@enter="handleOpen"
|
||||||
@close="close"
|
@close="close"
|
||||||
@after-enter="handleOpened"
|
@after-enter="handleOpened"
|
||||||
@ -127,9 +128,6 @@ function select(rowIndex: number, type: 'action' | 'panels', colIndex?: number)
|
|||||||
}
|
}
|
||||||
function handleClickModal() {
|
function handleClickModal() {
|
||||||
emit('click-modal')
|
emit('click-modal')
|
||||||
// if (props.closeOnClickModal) {
|
|
||||||
// close()
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
emit('cancel')
|
emit('cancel')
|
||||||
|
|||||||
@ -3,34 +3,15 @@
|
|||||||
|
|
||||||
.wot-theme-dark {
|
.wot-theme-dark {
|
||||||
@include b(calendar) {
|
@include b(calendar) {
|
||||||
@include e(cell) {
|
|
||||||
background-color: $-dark-background2;
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(label) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(value) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(title) {
|
@include e(title) {
|
||||||
color: $-dark-color;
|
color: $-dark-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.wd-calendar__arrow),
|
|
||||||
:deep(.wd-calendar__close) {
|
:deep(.wd-calendar__close) {
|
||||||
color: $-dark-color;
|
color: $-dark-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@include when(border) {
|
|
||||||
.wd-calendar__cell {
|
|
||||||
@include halfPixelBorder('top', $-cell-padding, $-dark-border-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(range-label-item) {
|
@include e(range-label-item) {
|
||||||
color: $-dark-color;
|
color: $-dark-color;
|
||||||
@ -47,123 +28,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include b(calendar) {
|
@include b(calendar) {
|
||||||
@include when(border) {
|
|
||||||
.wd-calendar__cell {
|
|
||||||
@include halfPixelBorder('top', $-cell-padding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(cell) {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
padding: $-cell-wrapper-padding $-cell-padding;
|
|
||||||
align-items: flex-start;
|
|
||||||
background-color: $-color-white;
|
|
||||||
text-decoration: none;
|
|
||||||
color: $-cell-title-color;
|
|
||||||
font-size: $-cell-title-fs;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: $-cell-line-height;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(cell) {
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-calendar__value {
|
|
||||||
color: $-input-disabled-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include when(align-right) {
|
|
||||||
.wd-calendar__value {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include when(error) {
|
|
||||||
.wd-calendar__value {
|
|
||||||
color: $-input-error-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.wd-calendar__arrow) {
|
|
||||||
color: $-input-error-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include when(large) {
|
|
||||||
font-size: $-cell-title-fs-large;
|
|
||||||
|
|
||||||
:deep(.wd-calendar__arrow) {
|
|
||||||
font-size: $-cell-icon-size-large;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include when(center) {
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
:deep(.wd-calendar__arrow) {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(error-message){
|
|
||||||
color: $-form-item-error-message-color;
|
|
||||||
font-size: $-form-item-error-message-font-size;
|
|
||||||
line-height: $-form-item-error-message-line-height;
|
|
||||||
text-align: left;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(label) {
|
|
||||||
position: relative;
|
|
||||||
width: $-input-cell-label-width;
|
|
||||||
margin-right: $-cell-padding;
|
|
||||||
color: $-cell-title-color;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
@include when(required) {
|
|
||||||
padding-left: 12px;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 2px;
|
|
||||||
content: '*';
|
|
||||||
font-size: $-cell-required-size;
|
|
||||||
line-height: 1.1;
|
|
||||||
color: $-cell-required-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(value-wraper) {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(value) {
|
|
||||||
flex: 1;
|
|
||||||
margin-right: 10px;
|
|
||||||
color: $-cell-value-color;
|
|
||||||
|
|
||||||
@include when(ellipsis) {
|
|
||||||
@include lineEllipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include m(placeholder) {
|
|
||||||
color: $-input-placeholder-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(body) {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include edeep(arrow) {
|
|
||||||
display: block;
|
|
||||||
font-size: $-cell-icon-size;
|
|
||||||
color: $-cell-arrow-color;
|
|
||||||
line-height: $-cell-line-height;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(header) {
|
@include e(header) {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@ -1,16 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: weisheng
|
* @Author: weisheng
|
||||||
* @Date: 2024-03-15 20:40:34
|
* @Date: 2024-03-15 20:40:34
|
||||||
* @LastEditTime: 2024-06-09 14:38:57
|
* @LastEditTime: 2024-11-13 13:18:15
|
||||||
* @LastEditors: weisheng
|
* @LastEditors: weisheng
|
||||||
* @Description:
|
* @Description:
|
||||||
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-calendar/types.ts
|
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-calendar\types.ts
|
||||||
* 记得注释
|
* 记得注释
|
||||||
*/
|
*/
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props'
|
import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props'
|
||||||
import type { CalendarFormatter, CalendarTimeFilter, CalendarType } from '../wd-calendar-view/types'
|
import type { CalendarFormatter, CalendarTimeFilter, CalendarType } from '../wd-calendar-view/types'
|
||||||
import type { FormItemRule } from '../wd-form/types'
|
|
||||||
|
|
||||||
export const calendarProps = {
|
export const calendarProps = {
|
||||||
...baseProps,
|
...baseProps,
|
||||||
@ -64,58 +63,10 @@ export const calendarProps = {
|
|||||||
* type 为 'datetime' 或 'datetimerange' 时有效,是否不展示秒修改
|
* type 为 'datetime' 或 'datetimerange' 时有效,是否不展示秒修改
|
||||||
*/
|
*/
|
||||||
hideSecond: makeBooleanProp(false),
|
hideSecond: makeBooleanProp(false),
|
||||||
/**
|
|
||||||
* 选择器左侧文案
|
|
||||||
*/
|
|
||||||
label: String,
|
|
||||||
/**
|
|
||||||
* 设置左侧标题宽度
|
|
||||||
*/
|
|
||||||
labelWidth: String,
|
|
||||||
/**
|
|
||||||
* 使用 label 插槽时设置该选项
|
|
||||||
*/
|
|
||||||
useLabelSlot: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 使用默认插槽时设置该选项
|
|
||||||
*/
|
|
||||||
useDefaultSlot: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 禁用
|
|
||||||
*/
|
|
||||||
disabled: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 只读
|
|
||||||
*/
|
|
||||||
readonly: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 选择器占位符
|
|
||||||
*/
|
|
||||||
placeholder: String,
|
|
||||||
/**
|
/**
|
||||||
* 弹出层标题
|
* 弹出层标题
|
||||||
*/
|
*/
|
||||||
title: String,
|
title: String,
|
||||||
/**
|
|
||||||
* 选择器的值靠右展示
|
|
||||||
*/
|
|
||||||
alignRight: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 是否为错误状态,错误状态时右侧内容为红色
|
|
||||||
*/
|
|
||||||
error: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 是否必填
|
|
||||||
*/
|
|
||||||
required: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 设置选择器大小,可选值:large
|
|
||||||
*/
|
|
||||||
size: String,
|
|
||||||
/**
|
|
||||||
* 是否垂直居中
|
|
||||||
*/
|
|
||||||
center: makeBooleanProp(false),
|
|
||||||
/**
|
/**
|
||||||
* 点击遮罩是否关闭
|
* 点击遮罩是否关闭
|
||||||
*/
|
*/
|
||||||
@ -132,18 +83,10 @@ export const calendarProps = {
|
|||||||
* 确定按钮文字
|
* 确定按钮文字
|
||||||
*/
|
*/
|
||||||
confirmText: String,
|
confirmText: String,
|
||||||
/**
|
|
||||||
* 自定义展示文案的格式化函数,返回一个字符串
|
|
||||||
*/
|
|
||||||
displayFormat: Function as PropType<CalendarDisplayFormat>,
|
|
||||||
/**
|
/**
|
||||||
* 自定义范围选择类型的面板内部回显,返回一个字符串
|
* 自定义范围选择类型的面板内部回显,返回一个字符串
|
||||||
*/
|
*/
|
||||||
innerDisplayFormat: Function as PropType<CalendarInnerDisplayFormat>,
|
innerDisplayFormat: Function as PropType<CalendarInnerDisplayFormat>,
|
||||||
/**
|
|
||||||
* 是否超出隐藏
|
|
||||||
*/
|
|
||||||
ellipsis: makeBooleanProp(false),
|
|
||||||
/**
|
/**
|
||||||
* 是否显示类型切换功能
|
* 是否显示类型切换功能
|
||||||
*/
|
*/
|
||||||
@ -164,23 +107,6 @@ export const calendarProps = {
|
|||||||
* 确定前校验函数,接收 { value, resolve } 参数,通过 resolve 继续执行,resolve 接收 1 个 boolean 参数
|
* 确定前校验函数,接收 { value, resolve } 参数,通过 resolve 继续执行,resolve 接收 1 个 boolean 参数
|
||||||
*/
|
*/
|
||||||
beforeConfirm: Function as PropType<CalendarBeforeConfirm>,
|
beforeConfirm: Function as PropType<CalendarBeforeConfirm>,
|
||||||
/**
|
|
||||||
* 表单域 model 字段名,在使用表单校验功能的情况下,该属性是必填的
|
|
||||||
*/
|
|
||||||
prop: String,
|
|
||||||
/**
|
|
||||||
* 表单验证规则,结合wd-form组件使用
|
|
||||||
*/
|
|
||||||
rules: makeArrayProp<FormItemRule>(),
|
|
||||||
customViewClass: makeStringProp(''),
|
|
||||||
/**
|
|
||||||
* label 外部自定义样式
|
|
||||||
*/
|
|
||||||
customLabelClass: makeStringProp(''),
|
|
||||||
/**
|
|
||||||
* value 外部自定义样式
|
|
||||||
*/
|
|
||||||
customValueClass: makeStringProp(''),
|
|
||||||
/**
|
/**
|
||||||
* 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
|
* 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,34 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="`wd-calendar ${cell.border.value ? 'is-border' : ''} ${customClass}`">
|
<view :class="`wd-calendar ${customClass}`">
|
||||||
<view class="wd-calendar__field" @click="open">
|
|
||||||
<slot v-if="useDefaultSlot"></slot>
|
|
||||||
<view
|
|
||||||
v-else
|
|
||||||
:class="`wd-calendar__cell ${disabled ? 'is-disabled' : ''} ${readonly ? 'is-readonly' : ''} ${alignRight ? 'is-align-right' : ''} ${
|
|
||||||
error ? 'is-error' : ''
|
|
||||||
} ${size ? 'is-' + size : ''} ${center ? 'is-center' : ''}`"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
v-if="label || useLabelSlot"
|
|
||||||
:class="`wd-calendar__label ${isRequired ? 'is-required' : ''} ${customLabelClass}`"
|
|
||||||
:style="labelWidth ? 'min-width:' + labelWidth + ';max-width:' + labelWidth + ';' : ''"
|
|
||||||
>
|
|
||||||
<block v-if="label">{{ label }}</block>
|
|
||||||
<slot v-else name="label"></slot>
|
|
||||||
</view>
|
|
||||||
<view class="wd-calendar__body">
|
|
||||||
<view class="wd-calendar__value-wraper">
|
|
||||||
<view
|
|
||||||
:class="`wd-calendar__value ${ellipsis ? 'is-ellipsis' : ''} ${customValueClass} ${showValue ? '' : 'wd-calendar__value--placeholder'}`"
|
|
||||||
>
|
|
||||||
{{ showValue || placeholder || translate('placeholder') }}
|
|
||||||
</view>
|
|
||||||
<wd-icon v-if="!disabled && !readonly" custom-class="wd-calendar__arrow" name="arrow-right" />
|
|
||||||
</view>
|
|
||||||
<view v-if="errorMessage" class="wd-calendar__error-message">{{ errorMessage }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<wd-action-sheet
|
<wd-action-sheet
|
||||||
v-model="pickerShow"
|
v-model="pickerShow"
|
||||||
:duration="250"
|
:duration="250"
|
||||||
@ -124,57 +95,11 @@ import { ref, computed, watch } from 'vue'
|
|||||||
import { dayjs } from '../common/dayjs'
|
import { dayjs } from '../common/dayjs'
|
||||||
import { deepClone, isArray, isEqual, padZero, requestAnimationFrame } from '../common/util'
|
import { deepClone, isArray, isEqual, padZero, requestAnimationFrame } from '../common/util'
|
||||||
import { getWeekNumber, isRange } from '../wd-calendar-view/utils'
|
import { getWeekNumber, isRange } from '../wd-calendar-view/utils'
|
||||||
import { useCell } from '../composables/useCell'
|
|
||||||
import { FORM_KEY, type FormItemRule } from '../wd-form/types'
|
|
||||||
import { useParent } from '../composables/useParent'
|
|
||||||
import { useTranslate } from '../composables/useTranslate'
|
import { useTranslate } from '../composables/useTranslate'
|
||||||
import { calendarProps, type CalendarExpose } from './types'
|
import { calendarProps, type CalendarExpose } from './types'
|
||||||
import type { CalendarType } from '../wd-calendar-view/types'
|
import type { CalendarType } from '../wd-calendar-view/types'
|
||||||
const { translate } = useTranslate('calendar')
|
const { translate } = useTranslate('calendar')
|
||||||
|
|
||||||
const defaultDisplayFormat = (value: number | number[], type: CalendarType): string => {
|
|
||||||
switch (type) {
|
|
||||||
case 'date':
|
|
||||||
return dayjs(value as number).format('YYYY-MM-DD')
|
|
||||||
case 'dates':
|
|
||||||
return (value as number[])
|
|
||||||
.map((item) => {
|
|
||||||
return dayjs(item).format('YYYY-MM-DD')
|
|
||||||
})
|
|
||||||
.join(', ')
|
|
||||||
case 'daterange':
|
|
||||||
return `${(value as number[])[0] ? dayjs((value as number[])[0]).format('YYYY-MM-DD') : translate('startTime')} ${translate('to')} ${
|
|
||||||
(value as number[])[1] ? dayjs((value as number[])[1]).format('YYYY-MM-DD') : translate('endTime')
|
|
||||||
}`
|
|
||||||
case 'datetime':
|
|
||||||
return dayjs(value as number).format('YYYY-MM-DD HH:mm:ss')
|
|
||||||
case 'datetimerange':
|
|
||||||
return `${(value as number[])[0] ? dayjs((value as number[])[0]).format(translate('timeFormat')) : translate('startTime')} ${translate(
|
|
||||||
'to'
|
|
||||||
)}\n${(value as number[])[1] ? dayjs((value as number[])[1]).format(translate('timeFormat')) : translate('endTime')}`
|
|
||||||
case 'week': {
|
|
||||||
const year = new Date(value as number).getFullYear()
|
|
||||||
const week = getWeekNumber(value as number)
|
|
||||||
return translate('weekFormat', year, padZero(week))
|
|
||||||
}
|
|
||||||
case 'weekrange': {
|
|
||||||
const year1 = new Date((value as number[])[0]).getFullYear()
|
|
||||||
const week1 = getWeekNumber((value as number[])[0])
|
|
||||||
const year2 = new Date((value as number[])[1]).getFullYear()
|
|
||||||
const week2 = getWeekNumber((value as number[])[1])
|
|
||||||
return `${(value as number[])[0] ? translate('weekFormat', year1, padZero(week1)) : translate('startWeek')} - ${
|
|
||||||
(value as number[])[1] ? translate('weekFormat', year2, padZero(week2)) : translate('endWeek')
|
|
||||||
}`
|
|
||||||
}
|
|
||||||
case 'month':
|
|
||||||
return dayjs(value as number).format('YYYY / MM')
|
|
||||||
case 'monthrange':
|
|
||||||
return `${(value as number[])[0] ? dayjs((value as number[])[0]).format('YYYY / MM') : translate('startMonth')} ${translate('to')} ${
|
|
||||||
(value as number[])[1] ? dayjs((value as number[])[1]).format('YYYY / MM') : translate('endMonth')
|
|
||||||
}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatRange = (value: number, rangeType: 'start' | 'end', type: CalendarType) => {
|
const formatRange = (value: number, rangeType: 'start' | 'end', type: CalendarType) => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'daterange':
|
case 'daterange':
|
||||||
@ -217,7 +142,6 @@ const lastTab = ref<number>(0)
|
|||||||
const currentType = ref<CalendarType>('date')
|
const currentType = ref<CalendarType>('date')
|
||||||
const lastCurrentType = ref<CalendarType>()
|
const lastCurrentType = ref<CalendarType>()
|
||||||
const inited = ref<boolean>(false)
|
const inited = ref<boolean>(false)
|
||||||
const cell = useCell()
|
|
||||||
const calendarView = ref()
|
const calendarView = ref()
|
||||||
const calendarTabs = ref()
|
const calendarTabs = ref()
|
||||||
|
|
||||||
@ -228,14 +152,6 @@ const rangeLabel = computed(() => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const showValue = computed(() => {
|
|
||||||
if ((!isArray(props.modelValue) && props.modelValue) || (isArray(props.modelValue) && props.modelValue.length)) {
|
|
||||||
return (props.displayFormat || defaultDisplayFormat)(props.modelValue, lastCurrentType.value || currentType.value)
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(val, oldVal) => {
|
(val, oldVal) => {
|
||||||
@ -250,7 +166,7 @@ watch(
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.type,
|
() => props.type,
|
||||||
(newValue, oldValue) => {
|
(newValue) => {
|
||||||
if (props.showTypeSwitch) {
|
if (props.showTypeSwitch) {
|
||||||
const tabs = ['date', 'week', 'month']
|
const tabs = ['date', 'week', 'month']
|
||||||
const rangeTabs = ['daterange', 'weekrange', 'monthrange']
|
const rangeTabs = ['daterange', 'weekrange', 'monthrange']
|
||||||
@ -278,31 +194,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const { parent: form } = useParent(FORM_KEY)
|
|
||||||
|
|
||||||
// 表单校验错误信息
|
|
||||||
const errorMessage = computed(() => {
|
|
||||||
if (form && props.prop && form.errorMessages && form.errorMessages[props.prop]) {
|
|
||||||
return form.errorMessages[props.prop]
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 是否展示必填
|
|
||||||
const isRequired = computed(() => {
|
|
||||||
let formRequired = false
|
|
||||||
if (form && form.props.rules) {
|
|
||||||
const rules = form.props.rules
|
|
||||||
for (const key in rules) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(rules, key) && key === props.prop && Array.isArray(rules[key])) {
|
|
||||||
formRequired = rules[key].some((rule: FormItemRule) => rule.required)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props.required || props.rules.some((rule) => rule.required) || formRequired
|
|
||||||
})
|
|
||||||
|
|
||||||
const range = computed(() => {
|
const range = computed(() => {
|
||||||
return (type: CalendarType) => {
|
return (type: CalendarType) => {
|
||||||
return isRange(type)
|
return isRange(type)
|
||||||
@ -314,10 +205,6 @@ function scrollIntoView() {
|
|||||||
}
|
}
|
||||||
// 对外暴露方法
|
// 对外暴露方法
|
||||||
function open() {
|
function open() {
|
||||||
const { disabled, readonly } = props
|
|
||||||
|
|
||||||
if (disabled || readonly) return
|
|
||||||
|
|
||||||
inited.value = true
|
inited.value = true
|
||||||
pickerShow.value = true
|
pickerShow.value = true
|
||||||
lastCalendarValue.value = deepClone(calendarValue.value)
|
lastCalendarValue.value = deepClone(calendarValue.value)
|
||||||
|
|||||||
@ -19,9 +19,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include when(border) {
|
@include when(border) {
|
||||||
.wd-cell__wrapper {
|
@include halfPixelBorder('top', 0, $-dark-border-color);
|
||||||
@include halfPixelBorder('top', 0, $-dark-border-color);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.wd-cell__arrow-right) {
|
:deep(.wd-cell__arrow-right) {
|
||||||
@ -32,45 +30,37 @@
|
|||||||
|
|
||||||
@include b(cell) {
|
@include b(cell) {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: $-cell-padding;
|
|
||||||
background-color: $-color-white;
|
background-color: $-color-white;
|
||||||
|
padding: $-cell-horizontal-padding $-cell-vertical-padding;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: $-cell-title-color;
|
color: $-cell-title-color;
|
||||||
line-height: $-cell-line-height;
|
line-height: $-cell-line-height;
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
|
||||||
@include when(border) {
|
@include when(border) {
|
||||||
.wd-cell__wrapper {
|
@include halfPixelBorder('top');
|
||||||
@include halfPixelBorder('top');
|
}
|
||||||
|
|
||||||
|
@include when(vertical) {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
.wd-cell__right {
|
||||||
|
margin-top: $-cell-vertical-top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wd-cell__value {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wd-cell__left {
|
||||||
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include e(wrapper) {
|
@include when(label) {
|
||||||
position: relative;
|
padding: $-cell-horizontal-padding-with-label $-cell-vertical-padding;
|
||||||
display: flex;
|
|
||||||
padding: $-cell-wrapper-padding $-cell-padding $-cell-wrapper-padding 0;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-start;
|
|
||||||
|
|
||||||
@include when(vertical) {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
.wd-cell__right {
|
|
||||||
margin-top: $-cell-vertical-top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wd-cell__value {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wd-cell__left {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include when(label) {
|
|
||||||
padding: $-cell-wrapper-padding-with-label $-cell-padding $-cell-wrapper-padding-with-label 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@include e(left) {
|
@include e(left) {
|
||||||
@ -80,7 +70,6 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: $-cell-title-fs;
|
font-size: $-cell-title-fs;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin-right: $-cell-padding;
|
|
||||||
|
|
||||||
@include when(required) {
|
@include when(required) {
|
||||||
padding-left: 12px;
|
padding-left: 12px;
|
||||||
@ -123,7 +112,7 @@
|
|||||||
line-height: $-cell-line-height;
|
line-height: $-cell-line-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include e(body){
|
@include e(body) {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +135,7 @@
|
|||||||
line-height: $-cell-line-height;
|
line-height: $-cell-line-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include e(error-message){
|
@include e(error-message) {
|
||||||
color: $-form-item-error-message-color;
|
color: $-form-item-error-message-color;
|
||||||
font-size: $-form-item-error-message-font-size;
|
font-size: $-form-item-error-message-font-size;
|
||||||
line-height: $-form-item-error-message-line-height;
|
line-height: $-form-item-error-message-line-height;
|
||||||
@ -163,14 +152,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include when(large) {
|
@include when(large) {
|
||||||
|
padding-top: $-cell-horizontal-padding-large;
|
||||||
|
padding-bottom: $-cell-horizontal-padding-large;
|
||||||
|
|
||||||
.wd-cell__title {
|
.wd-cell__title {
|
||||||
font-size: $-cell-title-fs-large;
|
font-size: $-cell-title-fs-large;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wd-cell__wrapper {
|
|
||||||
padding-top: $-cell-wrapper-padding-large;
|
|
||||||
padding-bottom: $-cell-wrapper-padding-large;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wd-cell__label {
|
.wd-cell__label {
|
||||||
font-size: $-cell-label-fs-large;
|
font-size: $-cell-label-fs-large;
|
||||||
@ -182,8 +170,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include when(center) {
|
@include when(center) {
|
||||||
.wd-cell__wrapper {
|
align-items: center;
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,47 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<view
|
<view
|
||||||
:class="['wd-cell', isBorder ? 'is-border' : '', size ? 'is-' + size : '', center ? 'is-center' : '', customClass]"
|
:class="['wd-cell', isBorder ? 'is-border' : '', size ? 'is-' + size : '', center ? 'is-center' : '', vertical ? 'is-vertical' : '', customClass]"
|
||||||
:style="customStyle"
|
:style="customStyle"
|
||||||
:hover-class="isLink || clickable ? 'is-hover' : 'none'"
|
:hover-class="isLink || clickable ? 'is-hover' : 'none'"
|
||||||
:hover-stay-time="70"
|
:hover-stay-time="70"
|
||||||
@click="onClick"
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
<view :class="['wd-cell__wrapper', vertical ? 'is-vertical' : '']">
|
<view
|
||||||
<view
|
:class="['wd-cell__left', isRequired ? 'is-required' : '']"
|
||||||
:class="['wd-cell__left', isRequired ? 'is-required' : '']"
|
:style="titleWidth ? 'min-width:' + titleWidth + ';max-width:' + titleWidth + ';' : ''"
|
||||||
:style="titleWidth ? 'min-width:' + titleWidth + ';max-width:' + titleWidth + ';' : ''"
|
>
|
||||||
>
|
<!--左侧icon部位-->
|
||||||
<!--左侧icon部位-->
|
<wd-icon v-if="icon" :name="icon" :custom-class="`wd-cell__icon ${customIconClass}`"></wd-icon>
|
||||||
<wd-icon v-if="icon" :name="icon" :custom-class="`wd-cell__icon ${customIconClass}`"></wd-icon>
|
<slot v-else name="icon" />
|
||||||
<slot v-else name="icon" />
|
|
||||||
|
|
||||||
<view class="wd-cell__title">
|
<view class="wd-cell__title">
|
||||||
<!--title BEGIN-->
|
<!--title BEGIN-->
|
||||||
<view v-if="title" :class="customTitleClass">{{ title }}</view>
|
<view v-if="title" :class="customTitleClass">{{ title }}</view>
|
||||||
<slot v-else name="title"></slot>
|
<slot v-else name="title"></slot>
|
||||||
<!--title END-->
|
<!--title END-->
|
||||||
|
|
||||||
<!--label BEGIN-->
|
<!--label BEGIN-->
|
||||||
<view v-if="label" :class="`wd-cell__label ${customLabelClass}`">{{ label }}</view>
|
<view v-if="label" :class="`wd-cell__label ${customLabelClass}`">{{ label }}</view>
|
||||||
<slot v-else name="label" />
|
<slot v-else name="label" />
|
||||||
<!--label END-->
|
<!--label END-->
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
<!--right content BEGIN-->
|
|
||||||
<view class="wd-cell__right">
|
|
||||||
<view class="wd-cell__body">
|
|
||||||
<!--文案内容-->
|
|
||||||
<view :class="`wd-cell__value ${customValueClass}`">
|
|
||||||
<slot>{{ value }}</slot>
|
|
||||||
</view>
|
|
||||||
<!--箭头-->
|
|
||||||
<wd-icon v-if="isLink" custom-class="wd-cell__arrow-right" name="arrow-right" />
|
|
||||||
<slot v-else name="right-icon" />
|
|
||||||
</view>
|
|
||||||
<view v-if="errorMessage" class="wd-cell__error-message">{{ errorMessage }}</view>
|
|
||||||
</view>
|
|
||||||
<!--right content END-->
|
|
||||||
</view>
|
</view>
|
||||||
|
<!--right content BEGIN-->
|
||||||
|
<view class="wd-cell__right">
|
||||||
|
<view class="wd-cell__body">
|
||||||
|
<!--文案内容-->
|
||||||
|
<view :class="`wd-cell__value ${customValueClass}`">
|
||||||
|
<slot>{{ value }}</slot>
|
||||||
|
</view>
|
||||||
|
<!--箭头-->
|
||||||
|
<wd-icon v-if="isLink" custom-class="wd-cell__arrow-right" name="arrow-right" />
|
||||||
|
<slot v-else name="right-icon" />
|
||||||
|
</view>
|
||||||
|
<view v-if="errorMessage" class="wd-cell__error-message">{{ errorMessage }}</view>
|
||||||
|
</view>
|
||||||
|
<!--right content END-->
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -98,10 +96,7 @@ const isRequired = computed(() => {
|
|||||||
return props.required || props.rules.some((rule) => rule.required) || formRequired
|
return props.required || props.rules.some((rule) => rule.required) || formRequired
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
function handleClick() {
|
||||||
* @description 点击cell的handle
|
|
||||||
*/
|
|
||||||
function onClick() {
|
|
||||||
const url = props.to
|
const url = props.to
|
||||||
|
|
||||||
if (props.clickable || props.isLink) {
|
if (props.clickable || props.isLink) {
|
||||||
|
|||||||
@ -3,30 +3,7 @@
|
|||||||
|
|
||||||
.wot-theme-dark {
|
.wot-theme-dark {
|
||||||
@include b(col-picker) {
|
@include b(col-picker) {
|
||||||
|
|
||||||
@include when(border) {
|
|
||||||
.wd-col-picker__cell {
|
|
||||||
@include halfPixelBorder('top', $-cell-padding, $-dark-border-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(label) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(cell) {
|
|
||||||
background-color: $-dark-background2;
|
|
||||||
color: $-dark-color;
|
|
||||||
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-col-picker__value {
|
|
||||||
color: $-dark-color3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(list-item) {
|
@include e(list-item) {
|
||||||
|
|
||||||
@include when(disabled) {
|
@include when(disabled) {
|
||||||
color: $-dark-color3;
|
color: $-dark-color3;
|
||||||
}
|
}
|
||||||
@ -36,18 +13,6 @@
|
|||||||
color: $-dark-color-gray;
|
color: $-dark-color-gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include e(value) {
|
|
||||||
color: $-dark-color;
|
|
||||||
|
|
||||||
@include m(placeholder) {
|
|
||||||
color: $-dark-color-gray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.wd-col-picker__arrow) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(list) {
|
@include e(list) {
|
||||||
color: $-dark-color;
|
color: $-dark-color;
|
||||||
}
|
}
|
||||||
@ -59,140 +24,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include b(col-picker) {
|
@include b(col-picker) {
|
||||||
@include when(border) {
|
|
||||||
.wd-col-picker__cell {
|
|
||||||
@include halfPixelBorder('top', $-cell-padding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(cell) {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
padding: $-cell-wrapper-padding $-cell-padding;
|
|
||||||
align-items: flex-start;
|
|
||||||
background-color: $-color-white;
|
|
||||||
text-decoration: none;
|
|
||||||
color: $-cell-title-color;
|
|
||||||
font-size: $-cell-title-fs;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: $-cell-line-height;
|
|
||||||
}
|
|
||||||
@include e(cell) {
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-col-picker__value {
|
|
||||||
color: $-input-disabled-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(align-right) {
|
|
||||||
.wd-col-picker__value {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(error) {
|
|
||||||
.wd-col-picker__value {
|
|
||||||
color: $-input-error-color;
|
|
||||||
}
|
|
||||||
:deep(.wd-col-picker__arrow) {
|
|
||||||
color: $-input-error-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(large) {
|
|
||||||
font-size: $-cell-title-fs-large;
|
|
||||||
|
|
||||||
:deep(.wd-col-picker__arrow) {
|
|
||||||
font-size: $-cell-icon-size-large;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(error-message){
|
|
||||||
color: $-form-item-error-message-color;
|
|
||||||
font-size: $-form-item-error-message-font-size;
|
|
||||||
line-height: $-form-item-error-message-line-height;
|
|
||||||
text-align: left;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
@include e(label) {
|
|
||||||
position: relative;
|
|
||||||
width: $-input-cell-label-width;
|
|
||||||
margin-right: $-cell-padding;
|
|
||||||
color: $-cell-title-color;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
@include when(required) {
|
|
||||||
padding-left: 12px;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 2px;
|
|
||||||
content: '*';
|
|
||||||
font-size: $-cell-required-size;
|
|
||||||
line-height: 1.1;
|
|
||||||
color: $-cell-required-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(value-wraper) {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
@include e(value) {
|
|
||||||
flex: 1;
|
|
||||||
margin-right: 10px;
|
|
||||||
color: $-cell-value-color;
|
|
||||||
|
|
||||||
@include when(ellipsis) {
|
|
||||||
@include lineEllipsis;
|
|
||||||
}
|
|
||||||
@include m(placeholder) {
|
|
||||||
color: $-input-placeholder-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(body) {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
@include edeep(arrow) {
|
|
||||||
display: block;
|
|
||||||
font-size: $-cell-icon-size;
|
|
||||||
color: $-cell-arrow-color;
|
|
||||||
line-height: $-cell-line-height;
|
|
||||||
}
|
|
||||||
@include e(selected) {
|
|
||||||
height: $-col-picker-selected-height;
|
|
||||||
font-size: $-col-picker-selected-fs;
|
|
||||||
color: $-col-picker-selected-color;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
@include e(selected-container){
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
@include e(selected-item) {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
height: $-col-picker-selected-height;
|
|
||||||
line-height: $-col-picker-selected-height;
|
|
||||||
padding: $-col-picker-selected-padding;
|
|
||||||
|
|
||||||
@include when(selected) {
|
|
||||||
font-weight: $-col-picker-selected-fw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(selected-line) {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 5px;
|
|
||||||
width: $-col-picker-line-width;
|
|
||||||
left: 0;
|
|
||||||
height: $-col-picker-line-height;
|
|
||||||
background: $-col-picker-line-color;
|
|
||||||
z-index: 1;
|
|
||||||
border-radius: calc($-col-picker-line-height / 2);
|
|
||||||
box-shadow: $-col-picker-line-box-shadow;
|
|
||||||
}
|
|
||||||
@include e(list-container){
|
@include e(list-container){
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
@include e(list) {
|
@include e(list) {
|
||||||
height: $-col-picker-list-height;
|
height: $-col-picker-list-height;
|
||||||
padding-bottom: $-col-picker-list-padding-bottom;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
color: $-col-picker-list-color;
|
color: $-col-picker-list-color;
|
||||||
|
|||||||
@ -1,6 +1,13 @@
|
|||||||
import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
|
import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
|
||||||
import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp, numericProp } from '../common/props'
|
import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp, numericProp } from '../common/props'
|
||||||
import type { FormItemRule } from '../wd-form/types'
|
|
||||||
|
export type ColPickerOption = {
|
||||||
|
label?: string
|
||||||
|
value?: string | number
|
||||||
|
tip?: string
|
||||||
|
disabled?: boolean
|
||||||
|
[key: PropertyKey]: any
|
||||||
|
}
|
||||||
|
|
||||||
export const colPickerProps = {
|
export const colPickerProps = {
|
||||||
...baseProps,
|
...baseProps,
|
||||||
@ -8,38 +15,14 @@ export const colPickerProps = {
|
|||||||
* 选中项
|
* 选中项
|
||||||
*/
|
*/
|
||||||
modelValue: makeRequiredProp(Array as PropType<Array<string | number>>),
|
modelValue: makeRequiredProp(Array as PropType<Array<string | number>>),
|
||||||
|
/**
|
||||||
|
* 是否显示
|
||||||
|
*/
|
||||||
|
visible: makeBooleanProp(false),
|
||||||
/**
|
/**
|
||||||
* 选择器数据,二维数组
|
* 选择器数据,二维数组
|
||||||
*/
|
*/
|
||||||
columns: makeArrayProp<Record<string, any>[]>(),
|
columns: makeArrayProp<ColPickerOption[]>(),
|
||||||
/**
|
|
||||||
* 选择器左侧文案
|
|
||||||
*/
|
|
||||||
label: String,
|
|
||||||
/**
|
|
||||||
* 设置左侧标题宽度
|
|
||||||
*/
|
|
||||||
labelWidth: makeStringProp('33%'),
|
|
||||||
/**
|
|
||||||
* 使用 label 插槽时设置该选项
|
|
||||||
*/
|
|
||||||
useLabelSlot: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 使用默认插槽时设置该选项
|
|
||||||
*/
|
|
||||||
useDefaultSlot: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 禁用
|
|
||||||
*/
|
|
||||||
disabled: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 只读
|
|
||||||
*/
|
|
||||||
readonly: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 选择器占位符
|
|
||||||
*/
|
|
||||||
placeholder: String,
|
|
||||||
/**
|
/**
|
||||||
* 弹出层标题
|
* 弹出层标题
|
||||||
*/
|
*/
|
||||||
@ -48,30 +31,10 @@ export const colPickerProps = {
|
|||||||
* 接收当前列的选中项 item、当前列下标、当前列选中项下标下一列数据处理函数 resolve、结束选择 finish
|
* 接收当前列的选中项 item、当前列下标、当前列选中项下标下一列数据处理函数 resolve、结束选择 finish
|
||||||
*/
|
*/
|
||||||
columnChange: Function as PropType<ColPickerColumnChange>,
|
columnChange: Function as PropType<ColPickerColumnChange>,
|
||||||
/**
|
|
||||||
* 自定义展示文案的格式化函数,返回一个字符串
|
|
||||||
*/
|
|
||||||
displayFormat: Function as PropType<ColPickerDisplayFormat>,
|
|
||||||
/**
|
/**
|
||||||
* 确定前校验函数,接收 (value, resolve) 参数,通过 resolve 继续执行 picker,resolve 接收 1 个 boolean 参数
|
* 确定前校验函数,接收 (value, resolve) 参数,通过 resolve 继续执行 picker,resolve 接收 1 个 boolean 参数
|
||||||
*/
|
*/
|
||||||
beforeConfirm: Function as PropType<ColPickerBeforeConfirm>,
|
beforeConfirm: Function as PropType<ColPickerBeforeConfirm>,
|
||||||
/**
|
|
||||||
* 选择器的值靠右展示
|
|
||||||
*/
|
|
||||||
alignRight: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 是否为错误状态,错误状态时右侧内容为红色
|
|
||||||
*/
|
|
||||||
error: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 是否必填
|
|
||||||
*/
|
|
||||||
required: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 设置选择器大小,可选值:large
|
|
||||||
*/
|
|
||||||
size: String,
|
|
||||||
/**
|
/**
|
||||||
* 选项对象中,value 对应的 key
|
* 选项对象中,value 对应的 key
|
||||||
*/
|
*/
|
||||||
@ -104,18 +67,6 @@ export const colPickerProps = {
|
|||||||
* 弹出面板是否设置底部安全距离(iphone X 类型的机型)
|
* 弹出面板是否设置底部安全距离(iphone X 类型的机型)
|
||||||
*/
|
*/
|
||||||
safeAreaInsetBottom: makeBooleanProp(true),
|
safeAreaInsetBottom: makeBooleanProp(true),
|
||||||
/**
|
|
||||||
* 是否超出隐藏
|
|
||||||
*/
|
|
||||||
ellipsis: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 表单域 model 字段名,在使用表单校验功能的情况下,该属性是必填的
|
|
||||||
*/
|
|
||||||
prop: String,
|
|
||||||
/**
|
|
||||||
* 表单验证规则,结合wd-form组件使用
|
|
||||||
*/
|
|
||||||
rules: makeArrayProp<FormItemRule>(),
|
|
||||||
/**
|
/**
|
||||||
* 底部条宽度,单位像素
|
* 底部条宽度,单位像素
|
||||||
*/
|
*/
|
||||||
@ -123,30 +74,21 @@ export const colPickerProps = {
|
|||||||
/**
|
/**
|
||||||
* 底部条高度,单位像素
|
* 底部条高度,单位像素
|
||||||
*/
|
*/
|
||||||
lineHeight: numericProp,
|
lineHeight: numericProp
|
||||||
/**
|
|
||||||
* label 外部自定义样式
|
|
||||||
*/
|
|
||||||
customViewClass: makeStringProp(''),
|
|
||||||
/**
|
|
||||||
* value 外部自定义样式
|
|
||||||
*/
|
|
||||||
customLabelClass: makeStringProp(''),
|
|
||||||
customValueClass: makeStringProp('')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ColPickerProps = ExtractPropTypes<typeof colPickerProps>
|
export type ColPickerProps = ExtractPropTypes<typeof colPickerProps>
|
||||||
|
|
||||||
export type ColPickerColumnChangeOption = {
|
export type ColPickerColumnChangeOption = {
|
||||||
selectedItem: Record<string, any>
|
selectedItem: ColPickerOption
|
||||||
index: number
|
index: number
|
||||||
rowIndex: number
|
rowIndex: number
|
||||||
resolve: (nextColumn: Record<string, any>[]) => void
|
resolve: (nextColumn: ColPickerOption[]) => void
|
||||||
finish: (isOk?: boolean) => void
|
finish: (isOk?: boolean) => void
|
||||||
}
|
}
|
||||||
export type ColPickerColumnChange = (option: ColPickerColumnChangeOption) => void
|
export type ColPickerColumnChange = (option: ColPickerColumnChangeOption) => void
|
||||||
export type ColPickerDisplayFormat = (selectedItems: Record<string, any>[]) => string
|
export type ColPickerDisplayFormat = (selectedItems: ColPickerOption[]) => string
|
||||||
export type ColPickerBeforeConfirm = (value: (string | number)[], selectedItems: Record<string, any>[], resolve: (isPass: boolean) => void) => void
|
export type ColPickerBeforeConfirm = (value: (string | number)[], selectedItems: ColPickerOption[], resolve: (isPass: boolean) => void) => void
|
||||||
|
|
||||||
export type ColPickerExpose = {
|
export type ColPickerExpose = {
|
||||||
// 关闭picker弹框
|
// 关闭picker弹框
|
||||||
|
|||||||
@ -1,86 +1,42 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="`wd-col-picker ${cell.border.value ? 'is-border' : ''} ${customClass}`" :style="customStyle">
|
<view :class="`wd-col-picker ${customClass}`" :style="customStyle">
|
||||||
<view class="wd-col-picker__field" @click="showPicker">
|
|
||||||
<slot v-if="useDefaultSlot"></slot>
|
|
||||||
<view
|
|
||||||
v-else
|
|
||||||
:class="`wd-col-picker__cell ${disabled && 'is-disabled'} ${readonly && 'is-readonly'} ${alignRight && 'is-align-right'} ${
|
|
||||||
error && 'is-error'
|
|
||||||
} ${size && 'is-' + size}`"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
v-if="label || useLabelSlot"
|
|
||||||
:class="`wd-col-picker__label ${isRequired && 'is-required'} ${customLabelClass}`"
|
|
||||||
:style="labelWidth ? 'min-width:' + labelWidth + ';max-width:' + labelWidth + ';' : ''"
|
|
||||||
>
|
|
||||||
<block v-if="label">{{ label }}</block>
|
|
||||||
<slot v-else name="label"></slot>
|
|
||||||
</view>
|
|
||||||
<view class="wd-col-picker__body">
|
|
||||||
<view class="wd-col-picker__value-wraper">
|
|
||||||
<view
|
|
||||||
:class="`wd-col-picker__value ${ellipsis && 'is-ellipsis'} ${customValueClass} ${showValue ? '' : 'wd-col-picker__value--placeholder'}`"
|
|
||||||
>
|
|
||||||
{{ showValue || placeholder || translate('placeholder') }}
|
|
||||||
</view>
|
|
||||||
<wd-icon v-if="!disabled && !readonly" custom-class="wd-col-picker__arrow" name="arrow-right" />
|
|
||||||
</view>
|
|
||||||
<view v-if="errorMessage" class="wd-col-picker__error-message">{{ errorMessage }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<wd-action-sheet
|
<wd-action-sheet
|
||||||
v-model="pickerShow"
|
v-model="pickerShow"
|
||||||
:duration="250"
|
:duration="250"
|
||||||
:title="title || translate('title')"
|
:title="title || translate('title')"
|
||||||
:close-on-click-modal="closeOnClickModal"
|
:close-on-click-modal="closeOnClickModal"
|
||||||
|
:hideWhenClose="false"
|
||||||
:z-index="zIndex"
|
:z-index="zIndex"
|
||||||
:safe-area-inset-bottom="safeAreaInsetBottom"
|
:safe-area-inset-bottom="safeAreaInsetBottom"
|
||||||
@open="handlePickerOpend"
|
@opened="handlePickerOpened"
|
||||||
@close="handlePickerClose"
|
@close="handlePickerClose"
|
||||||
@closed="handlePickerClosed"
|
@closed="handlePickerClosed"
|
||||||
>
|
>
|
||||||
<view class="wd-col-picker__selected">
|
<wd-tabs ref="tabs" v-model="currentCol" :animated="animated" slidable="always">
|
||||||
<scroll-view :scroll-x="true" scroll-with-animation :scroll-left="scrollLeft">
|
<wd-tab v-for="(col, colIndex) in innerColumns" :key="colIndex" :title="`${currentColumn[colIndex] || translate('select')}`" :name="colIndex">
|
||||||
<view class="wd-col-picker__selected-container">
|
<view class="wd-col-picker__list-container">
|
||||||
<view
|
<view class="wd-col-picker__list">
|
||||||
v-for="(_, colIndex) in selectList"
|
<view
|
||||||
:key="colIndex"
|
v-for="(item, index) in col"
|
||||||
:class="`wd-col-picker__selected-item ${colIndex === currentCol && 'is-selected'}`"
|
:key="index"
|
||||||
@click="handleColClick(colIndex)"
|
:class="`wd-col-picker__list-item ${innerValue[colIndex] && item[valueKey] === innerValue[colIndex] && 'is-selected'} ${
|
||||||
>
|
item.disabled && 'is-disabled'
|
||||||
{{ selectShowList[colIndex] || translate('select') }}
|
}`"
|
||||||
|
@click="chooseItem(colIndex, index)"
|
||||||
|
>
|
||||||
|
<view>
|
||||||
|
<view class="wd-col-picker__list-item-label">{{ item[labelKey] }}</view>
|
||||||
|
<view v-if="item[tipKey]" class="wd-col-picker__list-item-tip">{{ item[tipKey] }}</view>
|
||||||
|
</view>
|
||||||
|
<wd-icon custom-class="wd-col-picker__checked" name="check"></wd-icon>
|
||||||
|
</view>
|
||||||
|
<view v-if="loading" class="wd-col-picker__loading">
|
||||||
|
<wd-loading :color="loadingColor" />
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="wd-col-picker__selected-line" :style="state.lineStyle"></view>
|
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</wd-tab>
|
||||||
</view>
|
</wd-tabs>
|
||||||
<view class="wd-col-picker__list-container">
|
|
||||||
<view
|
|
||||||
v-for="(col, colIndex) in selectList"
|
|
||||||
:key="colIndex"
|
|
||||||
class="wd-col-picker__list"
|
|
||||||
:style="colIndex === currentCol ? 'display: block;' : 'display: none;'"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
v-for="(item, index) in col"
|
|
||||||
:key="index"
|
|
||||||
:class="`wd-col-picker__list-item ${pickerColSelected[colIndex] && item[valueKey] === pickerColSelected[colIndex] && 'is-selected'} ${
|
|
||||||
item.disabled && 'is-disabled'
|
|
||||||
}`"
|
|
||||||
@click="chooseItem(colIndex, index)"
|
|
||||||
>
|
|
||||||
<view>
|
|
||||||
<view class="wd-col-picker__list-item-label">{{ item[labelKey] }}</view>
|
|
||||||
<view v-if="item[tipKey]" class="wd-col-picker__list-item-tip">{{ item[tipKey] }}</view>
|
|
||||||
</view>
|
|
||||||
<wd-icon custom-class="wd-col-picker__checked" name="check"></wd-icon>
|
|
||||||
</view>
|
|
||||||
<view v-if="loading" class="wd-col-picker__loading">
|
|
||||||
<wd-loading :color="loadingColor" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</wd-action-sheet>
|
</wd-action-sheet>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@ -99,78 +55,41 @@ export default {
|
|||||||
import wdIcon from '../wd-icon/wd-icon.vue'
|
import wdIcon from '../wd-icon/wd-icon.vue'
|
||||||
import wdLoading from '../wd-loading/wd-loading.vue'
|
import wdLoading from '../wd-loading/wd-loading.vue'
|
||||||
import wdActionSheet from '../wd-action-sheet/wd-action-sheet.vue'
|
import wdActionSheet from '../wd-action-sheet/wd-action-sheet.vue'
|
||||||
import { computed, getCurrentInstance, onMounted, ref, watch, type CSSProperties, reactive, nextTick } from 'vue'
|
import { ref, watch, nextTick } from 'vue'
|
||||||
import { addUnit, debounce, getRect, isArray, isBoolean, isDef, isFunction, objToStyle } from '../common/util'
|
import { deepClone, isArray, isBoolean, isDef, isEqual } from '../common/util'
|
||||||
import { useCell } from '../composables/useCell'
|
|
||||||
import { FORM_KEY, type FormItemRule } from '../wd-form/types'
|
|
||||||
import { useParent } from '../composables/useParent'
|
|
||||||
import { useTranslate } from '../composables/useTranslate'
|
import { useTranslate } from '../composables/useTranslate'
|
||||||
import { colPickerProps, type ColPickerExpose } from './types'
|
import { colPickerProps, type ColPickerExpose, type ColPickerOption } from './types'
|
||||||
|
import type { TabsInstance } from '../wd-tabs/types'
|
||||||
|
|
||||||
const { translate } = useTranslate('col-picker')
|
const { translate } = useTranslate('col-picker')
|
||||||
|
const tabs = ref<TabsInstance>()
|
||||||
const $container = '.wd-col-picker__selected-container'
|
|
||||||
const $item = '.wd-col-picker__selected-item'
|
|
||||||
|
|
||||||
const props = defineProps(colPickerProps)
|
const props = defineProps(colPickerProps)
|
||||||
const emit = defineEmits(['close', 'update:modelValue', 'confirm'])
|
const emit = defineEmits(['close', 'update:modelValue', 'update:visible', 'confirm'])
|
||||||
|
const innerValue = ref(props.modelValue) // 当前选择值
|
||||||
|
const innerColumns = ref<ColPickerOption[][]>(props.columns) // 全部列数据
|
||||||
|
const currentColumn = ref<ColPickerOption[]>([]) // 当前展示列数据
|
||||||
|
const animated = ref<boolean>(false) // 是否开启切换动画 弹窗打开后开启
|
||||||
|
|
||||||
const pickerShow = ref<boolean>(false)
|
const pickerShow = ref<boolean>(false)
|
||||||
const currentCol = ref<number>(0)
|
const currentCol = ref<number>(0)
|
||||||
const selectList = ref<Record<string, any>[][]>([])
|
|
||||||
const pickerColSelected = ref<(string | number)[]>([])
|
|
||||||
const selectShowList = ref<Record<string, any>[]>([])
|
|
||||||
const loading = ref<boolean>(false)
|
const loading = ref<boolean>(false)
|
||||||
const isChange = ref<boolean>(false)
|
const lastSelectList = ref<ColPickerOption[][]>([])
|
||||||
const lastSelectList = ref<Record<string, any>[][]>([])
|
|
||||||
const lastPickerColSelected = ref<(string | number)[]>([])
|
const lastPickerColSelected = ref<(string | number)[]>([])
|
||||||
const scrollLeft = ref<number>(0)
|
|
||||||
const inited = ref<boolean>(false)
|
|
||||||
const isCompleting = ref<boolean>(false)
|
const isCompleting = ref<boolean>(false)
|
||||||
|
|
||||||
const state = reactive({
|
watch(() => props.modelValue, updateInnerValue)
|
||||||
lineStyle: 'display:none;' // 激活项边框线样式
|
|
||||||
})
|
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as any
|
|
||||||
|
|
||||||
const cell = useCell()
|
|
||||||
|
|
||||||
const updateLineAndScroll = debounce(function (animation = true) {
|
|
||||||
setLineStyle(animation)
|
|
||||||
lineScrollIntoView()
|
|
||||||
}, 50)
|
|
||||||
|
|
||||||
const showValue = computed(() => {
|
|
||||||
const selectedItems = (props.modelValue || []).map((item, colIndex) => {
|
|
||||||
return getSelectedItem(item, colIndex, selectList.value)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (props.displayFormat) {
|
|
||||||
return props.displayFormat(selectedItems)
|
|
||||||
} else {
|
|
||||||
return selectedItems
|
|
||||||
.map((item) => {
|
|
||||||
return item[props.labelKey]
|
|
||||||
})
|
|
||||||
.join('')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.visible,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (newValue === pickerColSelected.value) return
|
if (newValue) {
|
||||||
pickerColSelected.value = newValue
|
open()
|
||||||
newValue.map((item, colIndex) => {
|
} else {
|
||||||
return getSelectedItem(item, colIndex, selectList.value)[props.labelKey]
|
close()
|
||||||
})
|
}
|
||||||
handleAutoComplete()
|
|
||||||
},
|
},
|
||||||
{
|
{ deep: true, immediate: true }
|
||||||
deep: true,
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -181,138 +100,76 @@ watch(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (newValue.length === 0 && !oldValue) return
|
if (newValue.length === 0 && !oldValue) return
|
||||||
|
innerColumns.value = deepClone(newValue)
|
||||||
const newSelectedList = newValue.slice(0)
|
currentColumn.value = innerValue.value.map((item, colIndex) => {
|
||||||
|
return getSelectedItem(item, colIndex, innerColumns.value)[props.labelKey]
|
||||||
selectList.value = newSelectedList
|
|
||||||
|
|
||||||
selectShowList.value = pickerColSelected.value.map((item, colIndex) => {
|
|
||||||
return getSelectedItem(item, colIndex, newSelectedList)[props.labelKey]
|
|
||||||
})
|
})
|
||||||
lastSelectList.value = newSelectedList
|
lastSelectList.value = deepClone(innerColumns.value)
|
||||||
|
|
||||||
if (newSelectedList.length > 0) {
|
|
||||||
currentCol.value = newSelectedList.length - 1
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true,
|
immediate: true,
|
||||||
immediate: true
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.columnChange,
|
|
||||||
(fn) => {
|
|
||||||
if (fn && !isFunction(fn)) {
|
|
||||||
console.error('The type of columnChange must be Function')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
deep: true,
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.displayFormat,
|
|
||||||
(fn) => {
|
|
||||||
if (fn && !isFunction(fn)) {
|
|
||||||
console.error('The type of displayFormat must be Function')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
deep: true,
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.beforeConfirm,
|
|
||||||
(fn) => {
|
|
||||||
if (fn && !isFunction(fn)) {
|
|
||||||
console.error('The type of beforeConfirm must be Function')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
deep: true,
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const { parent: form } = useParent(FORM_KEY)
|
|
||||||
|
|
||||||
// 表单校验错误信息
|
|
||||||
const errorMessage = computed(() => {
|
|
||||||
if (form && props.prop && form.errorMessages && form.errorMessages[props.prop]) {
|
|
||||||
return form.errorMessages[props.prop]
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 是否展示必填
|
|
||||||
const isRequired = computed(() => {
|
|
||||||
let formRequired = false
|
|
||||||
if (form && form.props.rules) {
|
|
||||||
const rules = form.props.rules
|
|
||||||
for (const key in rules) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(rules, key) && key === props.prop && Array.isArray(rules[key])) {
|
|
||||||
formRequired = rules[key].some((rule: FormItemRule) => rule.required)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props.required || props.rules.some((rule) => rule.required) || formRequired
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
inited.value = true
|
|
||||||
})
|
|
||||||
|
|
||||||
// 打开弹框
|
// 打开弹框
|
||||||
function open() {
|
function open() {
|
||||||
showPicker()
|
updateInnerValue()
|
||||||
|
pickerShow.value = true
|
||||||
|
lastPickerColSelected.value = deepClone(innerValue.value)
|
||||||
|
lastSelectList.value = deepClone(innerColumns.value)
|
||||||
}
|
}
|
||||||
// 关闭弹框
|
// 关闭弹框
|
||||||
function close() {
|
function close() {
|
||||||
handlePickerClose()
|
|
||||||
}
|
|
||||||
function handlePickerOpend() {
|
|
||||||
updateLineAndScroll(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
function handlePickerClose() {
|
|
||||||
pickerShow.value = false
|
pickerShow.value = false
|
||||||
emit('close')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePickerClosed() {
|
function updateInnerValue() {
|
||||||
if (isChange.value) {
|
if (isEqual(props.modelValue, innerValue.value)) return
|
||||||
setTimeout(() => {
|
innerValue.value = props.modelValue
|
||||||
selectList.value = lastSelectList.value.slice(0)
|
handleAutoComplete()
|
||||||
pickerColSelected.value = lastPickerColSelected.value.slice(0)
|
}
|
||||||
selectShowList.value = lastPickerColSelected.value.map((item, colIndex) => {
|
|
||||||
return getSelectedItem(item, colIndex, lastSelectList.value)[props.labelKey]
|
/**
|
||||||
})
|
* 弹出框打开后
|
||||||
currentCol.value = lastSelectList.value.length - 1
|
*/
|
||||||
isChange.value = false
|
function handlePickerOpened() {
|
||||||
}, 250)
|
if (isDef(tabs.value)) {
|
||||||
|
tabs.value?.updateLineStyle(false)
|
||||||
|
animated.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPicker() {
|
/**
|
||||||
const { disabled, readonly } = props
|
* 弹出框关闭时
|
||||||
|
*/
|
||||||
if (disabled || readonly) return
|
function handlePickerClose() {
|
||||||
pickerShow.value = true
|
emit('update:visible', false)
|
||||||
lastPickerColSelected.value = pickerColSelected.value.slice(0)
|
emit('close')
|
||||||
lastSelectList.value = selectList.value.slice(0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelectedItem(value: string | number, colIndex: number, selectList: Record<string, any>[][]) {
|
/**
|
||||||
|
* 弹出框关闭后
|
||||||
|
*/
|
||||||
|
function handlePickerClosed() {
|
||||||
|
animated.value = false
|
||||||
|
setTimeout(() => {
|
||||||
|
innerColumns.value = lastSelectList.value.slice(0)
|
||||||
|
innerValue.value = lastPickerColSelected.value.slice(0)
|
||||||
|
currentColumn.value = lastPickerColSelected.value.map((item, colIndex) => {
|
||||||
|
return getSelectedItem(item, colIndex, lastSelectList.value)[props.labelKey]
|
||||||
|
})
|
||||||
|
currentCol.value = lastSelectList.value.length - 1
|
||||||
|
if (isDef(tabs.value)) {
|
||||||
|
tabs.value.updateLineStyle(false)
|
||||||
|
}
|
||||||
|
}, 250)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedItem(value: string | number, colIndex: number, innerColumns: ColPickerOption[][]) {
|
||||||
const { valueKey, labelKey } = props
|
const { valueKey, labelKey } = props
|
||||||
if (selectList[colIndex]) {
|
if (innerColumns[colIndex]) {
|
||||||
const selecteds = selectList[colIndex].filter((item) => {
|
const selecteds = innerColumns[colIndex].filter((item) => {
|
||||||
return item[valueKey] === value
|
return item[valueKey] === value
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -328,26 +185,20 @@ function getSelectedItem(value: string | number, colIndex: number, selectList: R
|
|||||||
}
|
}
|
||||||
|
|
||||||
function chooseItem(colIndex: number, index: number) {
|
function chooseItem(colIndex: number, index: number) {
|
||||||
const item = selectList.value[colIndex][index]
|
const item = innerColumns.value[colIndex][index]
|
||||||
if (item.disabled) return
|
if (item.disabled) return
|
||||||
|
|
||||||
const newPickerColSelected = pickerColSelected.value.slice(0, colIndex)
|
const newPickerColSelected = innerValue.value.slice(0, colIndex)
|
||||||
newPickerColSelected.push(item[props.valueKey])
|
newPickerColSelected.push(item[props.valueKey])
|
||||||
isChange.value = true
|
innerValue.value = newPickerColSelected
|
||||||
pickerColSelected.value = newPickerColSelected
|
innerColumns.value = innerColumns.value.slice(0, colIndex + 1)
|
||||||
selectList.value = selectList.value.slice(0, colIndex + 1)
|
currentColumn.value = newPickerColSelected.map((item, colIndex) => {
|
||||||
selectShowList.value = newPickerColSelected.map((item, colIndex) => {
|
return getSelectedItem(item, colIndex, innerColumns.value)[props.labelKey]
|
||||||
return getSelectedItem(item, colIndex, selectList.value)[props.labelKey]
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (selectShowList.value[colIndex] && colIndex === currentCol.value) {
|
|
||||||
updateLineAndScroll(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
handleColChange(colIndex, item, index)
|
handleColChange(colIndex, item, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleColChange(colIndex: number, item: Record<string, any>, index: number, callback?: () => void) {
|
function handleColChange(colIndex: number, item: ColPickerOption, index: number, callback?: () => void) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
const { columnChange, beforeConfirm } = props
|
const { columnChange, beforeConfirm } = props
|
||||||
columnChange &&
|
columnChange &&
|
||||||
@ -355,24 +206,20 @@ function handleColChange(colIndex: number, item: Record<string, any>, index: num
|
|||||||
selectedItem: item,
|
selectedItem: item,
|
||||||
index: colIndex,
|
index: colIndex,
|
||||||
rowIndex: index,
|
rowIndex: index,
|
||||||
resolve: (nextColumn: Record<string, any>[]) => {
|
resolve: (nextColumn: ColPickerOption[]) => {
|
||||||
if (!isArray(nextColumn)) {
|
if (!isArray(nextColumn)) {
|
||||||
console.error('[wot design] error(wd-col-picker): the data of each column of wd-col-picker should be an array')
|
console.error('[wot design] error(wd-col-picker): the data of each column of wd-col-picker should be an array')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
innerColumns.value[colIndex + 1] = nextColumn
|
||||||
const newSelectList = selectList.value.slice(0)
|
|
||||||
newSelectList[colIndex + 1] = nextColumn
|
|
||||||
|
|
||||||
selectList.value = newSelectList
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
currentCol.value = colIndex + 1
|
nextTick(() => {
|
||||||
|
currentCol.value = colIndex + 1
|
||||||
updateLineAndScroll(true)
|
})
|
||||||
if (typeof callback === 'function') {
|
if (typeof callback === 'function') {
|
||||||
isCompleting.value = false
|
isCompleting.value = false
|
||||||
selectShowList.value = pickerColSelected.value.map((item, colIndex) => {
|
currentColumn.value = innerValue.value.map((item, colIndex) => {
|
||||||
return getSelectedItem(item, colIndex, selectList.value)[props.labelKey]
|
return getSelectedItem(item, colIndex, innerColumns.value)[props.labelKey]
|
||||||
})
|
})
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
@ -391,9 +238,9 @@ function handleColChange(colIndex: number, item: Record<string, any>, index: num
|
|||||||
|
|
||||||
if (beforeConfirm) {
|
if (beforeConfirm) {
|
||||||
beforeConfirm(
|
beforeConfirm(
|
||||||
pickerColSelected.value,
|
innerValue.value,
|
||||||
pickerColSelected.value.map((item, colIndex) => {
|
innerValue.value.map((item, colIndex) => {
|
||||||
return getSelectedItem(item, colIndex, selectList.value)
|
return getSelectedItem(item, colIndex, innerColumns.value)
|
||||||
}),
|
}),
|
||||||
(isPass: boolean) => {
|
(isPass: boolean) => {
|
||||||
if (isPass) {
|
if (isPass) {
|
||||||
@ -410,68 +257,18 @@ function handleColChange(colIndex: number, item: Record<string, any>, index: num
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
function onConfirm() {
|
function onConfirm() {
|
||||||
isChange.value = false
|
|
||||||
loading.value = false
|
loading.value = false
|
||||||
pickerShow.value = false
|
pickerShow.value = false
|
||||||
|
lastPickerColSelected.value = deepClone(innerValue.value)
|
||||||
emit('update:modelValue', pickerColSelected.value)
|
lastSelectList.value = deepClone(innerColumns.value)
|
||||||
|
emit('update:modelValue', innerValue.value)
|
||||||
emit('confirm', {
|
emit('confirm', {
|
||||||
value: pickerColSelected.value,
|
value: innerValue.value,
|
||||||
selectedItems: pickerColSelected.value.map((item, colIndex) => {
|
selectedItems: innerValue.value.map((item, colIndex) => {
|
||||||
return getSelectedItem(item, colIndex, selectList.value)
|
return getSelectedItem(item, colIndex, innerColumns.value)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
emit('update:visible', false)
|
||||||
function handleColClick(index: number) {
|
|
||||||
isChange.value = true
|
|
||||||
currentCol.value = index
|
|
||||||
updateLineAndScroll(true)
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @description 更新navBar underline的偏移量
|
|
||||||
* @param {Boolean} animation 是否伴随动画
|
|
||||||
*/
|
|
||||||
function setLineStyle(animation: boolean = true) {
|
|
||||||
if (!inited.value) return
|
|
||||||
const { lineWidth, lineHeight } = props
|
|
||||||
getRect($item, true, proxy)
|
|
||||||
.then((rects) => {
|
|
||||||
const lineStyle: CSSProperties = {}
|
|
||||||
if (isDef(lineWidth)) {
|
|
||||||
lineStyle.width = addUnit(lineWidth)
|
|
||||||
}
|
|
||||||
if (isDef(lineHeight)) {
|
|
||||||
lineStyle.height = addUnit(lineHeight)
|
|
||||||
lineStyle.borderRadius = `calc(${addUnit(lineHeight)} / 2)`
|
|
||||||
}
|
|
||||||
const rect = rects[currentCol.value]
|
|
||||||
let left = rects.slice(0, currentCol.value).reduce((prev, curr) => prev + Number(curr.width), 0) + Number(rect.width) / 2
|
|
||||||
lineStyle.transform = `translateX(${left}px) translateX(-50%)`
|
|
||||||
|
|
||||||
if (animation) {
|
|
||||||
lineStyle.transition = 'width 300ms ease, transform 300ms ease'
|
|
||||||
}
|
|
||||||
|
|
||||||
state.lineStyle = objToStyle(lineStyle)
|
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @description scroll-view滑动到active的tab_nav
|
|
||||||
*/
|
|
||||||
function lineScrollIntoView() {
|
|
||||||
if (!inited.value) return
|
|
||||||
Promise.all([getRect($item, true, proxy), getRect($container, false, proxy)])
|
|
||||||
.then(([navItemsRects, navRect]) => {
|
|
||||||
if (!isArray(navItemsRects) || navItemsRects.length === 0) return
|
|
||||||
// 选中元素
|
|
||||||
const selectItem = navItemsRects[currentCol.value]
|
|
||||||
// 选中元素之前的节点的宽度总和
|
|
||||||
const offsetLeft = navItemsRects.slice(0, currentCol.value).reduce((prev, curr) => prev + Number(curr.width), 0)
|
|
||||||
// scroll-view滑动到selectItem的偏移量
|
|
||||||
scrollLeft.value = offsetLeft - ((navRect as any).width - Number(selectItem.width)) / 2
|
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 递归列数据补齐
|
// 递归列数据补齐
|
||||||
@ -480,7 +277,7 @@ function diffColumns(colIndex: number) {
|
|||||||
const item = colIndex === -1 ? {} : { [props.valueKey]: props.modelValue[colIndex] }
|
const item = colIndex === -1 ? {} : { [props.valueKey]: props.modelValue[colIndex] }
|
||||||
handleColChange(colIndex, item, -1, () => {
|
handleColChange(colIndex, item, -1, () => {
|
||||||
// 如果 columns 长度还小于 value 长度,colIndex + 1,继续递归补齐
|
// 如果 columns 长度还小于 value 长度,colIndex + 1,继续递归补齐
|
||||||
if (selectList.value.length < props.modelValue.length) {
|
if (innerColumns.value.length < props.modelValue.length) {
|
||||||
diffColumns(colIndex + 1)
|
diffColumns(colIndex + 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -488,11 +285,11 @@ function diffColumns(colIndex: number) {
|
|||||||
function handleAutoComplete() {
|
function handleAutoComplete() {
|
||||||
if (props.autoComplete) {
|
if (props.autoComplete) {
|
||||||
// 如果 columns 数组长度为空,或者长度小于 value 的长度,自动触发 columnChange 来补齐数据
|
// 如果 columns 数组长度为空,或者长度小于 value 的长度,自动触发 columnChange 来补齐数据
|
||||||
if (selectList.value.length < props.modelValue.length || selectList.value.length === 0) {
|
if (innerColumns.value.length < props.modelValue.length || innerColumns.value.length === 0) {
|
||||||
// isCompleting 是否在自动补全,锁操作
|
// isCompleting 是否在自动补全,锁操作
|
||||||
if (!isCompleting.value) {
|
if (!isCompleting.value) {
|
||||||
// 如果 columns 长度为空,则传入的 colIndex 为 -1
|
// 如果 columns 长度为空,则传入的 colIndex 为 -1
|
||||||
const colIndex = selectList.value.length === 0 ? -1 : selectList.value.length - 1
|
const colIndex = innerColumns.value.length === 0 ? -1 : innerColumns.value.length - 1
|
||||||
diffColumns(colIndex)
|
diffColumns(colIndex)
|
||||||
}
|
}
|
||||||
isCompleting.value = true
|
isCompleting.value = true
|
||||||
|
|||||||
@ -3,37 +3,10 @@
|
|||||||
|
|
||||||
.wot-theme-dark {
|
.wot-theme-dark {
|
||||||
@include b(picker) {
|
@include b(picker) {
|
||||||
@include e(cell) {
|
|
||||||
background-color: $-dark-background2;
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(title) {
|
@include e(title) {
|
||||||
color: $-dark-color;
|
color: $-dark-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include e(label) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
@include e(value) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(placeholder) {
|
|
||||||
color: $-dark-color-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@include when(border) {
|
|
||||||
.wd-picker__cell {
|
|
||||||
@include halfPixelBorder('top', $-cell-padding, $-dark-border-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.wd-picker__arrow){
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(action) {
|
@include e(action) {
|
||||||
@include m(cancel) {
|
@include m(cancel) {
|
||||||
color: $-dark-color;
|
color: $-dark-color;
|
||||||
@ -61,118 +34,6 @@
|
|||||||
padding-bottom: var(--window-bottom);
|
padding-bottom: var(--window-bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@include when(border) {
|
|
||||||
.wd-picker__cell {
|
|
||||||
@include halfPixelBorder("top", $-cell-padding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(large) {
|
|
||||||
.wd-picker__cell {
|
|
||||||
font-size: $-cell-title-fs-large;
|
|
||||||
}
|
|
||||||
:deep(.wd-picker__arrow) {
|
|
||||||
font-size: $-cell-icon-size-large;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(error) {
|
|
||||||
.wd-picker__value,
|
|
||||||
.wd-picker__placeholder {
|
|
||||||
color: $-input-error-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.wd-picker__arrow){
|
|
||||||
color: $-input-error-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(align-right) {
|
|
||||||
.wd-picker__value {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(cell) {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
padding: $-cell-wrapper-padding $-cell-padding;
|
|
||||||
align-items: flex-start;
|
|
||||||
background-color: $-color-white;
|
|
||||||
text-decoration: none;
|
|
||||||
color: $-cell-title-color;
|
|
||||||
font-size: $-cell-title-fs;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: $-cell-line-height;
|
|
||||||
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-picker__value {
|
|
||||||
color: $-input-disabled-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-picker__value {
|
|
||||||
color: $-picker-column-disabled-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(error-message){
|
|
||||||
color: $-form-item-error-message-color;
|
|
||||||
font-size: $-form-item-error-message-font-size;
|
|
||||||
line-height: $-form-item-error-message-line-height;
|
|
||||||
text-align: left;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(label) {
|
|
||||||
position: relative;
|
|
||||||
width: $-input-cell-label-width;
|
|
||||||
margin-right: $-cell-padding;
|
|
||||||
color: $-cell-title-color;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
@include when(required) {
|
|
||||||
padding-left: 12px;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 2px;
|
|
||||||
content: "*";
|
|
||||||
font-size: $-cell-required-size;
|
|
||||||
line-height: 1.1;
|
|
||||||
color: $-cell-required-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(value-wraper) {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(value) {
|
|
||||||
flex: 1;
|
|
||||||
margin-right: 10px;
|
|
||||||
color: $-cell-value-color;
|
|
||||||
|
|
||||||
@include when(ellipsis) {
|
|
||||||
@include lineEllipsis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(body) {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(placeholder) {
|
|
||||||
color: $-input-placeholder-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include edeep(arrow) {
|
|
||||||
display: block;
|
|
||||||
font-size: $-cell-icon-size;
|
|
||||||
color: $-cell-arrow-color;
|
|
||||||
line-height: $-cell-line-height;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(toolbar) {
|
@include e(toolbar) {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -1,26 +1,9 @@
|
|||||||
import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
|
import type { ComponentPublicInstance, ExtractPropTypes, PropType } from 'vue'
|
||||||
import { baseProps, makeArrayProp, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props'
|
import { baseProps, makeBooleanProp, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props'
|
||||||
import type { DateTimeType, DatetimePickerViewFilter, DatetimePickerViewFormatter } from '../wd-datetime-picker-view/types'
|
import type { DateTimeType, DatetimePickerViewFilter, DatetimePickerViewFormatter } from '../wd-datetime-picker-view/types'
|
||||||
import type { FormItemRule } from '../wd-form/types'
|
|
||||||
|
|
||||||
export const datetimePickerProps = {
|
export const datetimePickerProps = {
|
||||||
...baseProps,
|
...baseProps,
|
||||||
/**
|
|
||||||
* 选择器左侧文案,label可以不传
|
|
||||||
*/
|
|
||||||
label: String,
|
|
||||||
/**
|
|
||||||
* 选择器占位符
|
|
||||||
*/
|
|
||||||
placeholder: String,
|
|
||||||
/**
|
|
||||||
* 禁用
|
|
||||||
*/
|
|
||||||
disabled: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 只读
|
|
||||||
*/
|
|
||||||
readonly: makeBooleanProp(false),
|
|
||||||
/**
|
/**
|
||||||
* 加载中
|
* 加载中
|
||||||
*/
|
*/
|
||||||
@ -41,34 +24,6 @@ export const datetimePickerProps = {
|
|||||||
* 确认按钮文案
|
* 确认按钮文案
|
||||||
*/
|
*/
|
||||||
confirmButtonText: String,
|
confirmButtonText: String,
|
||||||
/**
|
|
||||||
* 是否必填
|
|
||||||
*/
|
|
||||||
required: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 设置选择器大小,可选值:large
|
|
||||||
*/
|
|
||||||
size: String,
|
|
||||||
/**
|
|
||||||
* 设置左侧标题宽度
|
|
||||||
*/
|
|
||||||
labelWidth: makeStringProp('33%'),
|
|
||||||
/**
|
|
||||||
* 使用默认插槽
|
|
||||||
*/
|
|
||||||
useDefaultSlot: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* label 使用插槽
|
|
||||||
*/
|
|
||||||
useLabelSlot: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 是否为错误状态,错误状态时右侧内容为红色
|
|
||||||
*/
|
|
||||||
error: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 选择器的值靠右展示
|
|
||||||
*/
|
|
||||||
alignRight: makeBooleanProp(false),
|
|
||||||
/**
|
/**
|
||||||
* 点击遮罩是否关闭
|
* 点击遮罩是否关闭
|
||||||
*/
|
*/
|
||||||
@ -77,10 +32,6 @@ export const datetimePickerProps = {
|
|||||||
* 弹出面板是否设置底部安全距离(iphone X 类型的机型)
|
* 弹出面板是否设置底部安全距离(iphone X 类型的机型)
|
||||||
*/
|
*/
|
||||||
safeAreaInsetBottom: makeBooleanProp(true),
|
safeAreaInsetBottom: makeBooleanProp(true),
|
||||||
/**
|
|
||||||
* 是否超出隐藏
|
|
||||||
*/
|
|
||||||
ellipsis: makeBooleanProp(false),
|
|
||||||
/**
|
/**
|
||||||
* picker内部滚筒高
|
* picker内部滚筒高
|
||||||
*/
|
*/
|
||||||
@ -147,30 +98,10 @@ export const datetimePickerProps = {
|
|||||||
* 弹窗层级
|
* 弹窗层级
|
||||||
*/
|
*/
|
||||||
zIndex: makeNumberProp(15),
|
zIndex: makeNumberProp(15),
|
||||||
/**
|
|
||||||
* 表单域 model 字段名,在使用表单校验功能的情况下,该属性是必填的
|
|
||||||
*/
|
|
||||||
prop: String,
|
|
||||||
/**
|
|
||||||
* 表单验证规则,结合wd-form组件使用
|
|
||||||
*/
|
|
||||||
rules: makeArrayProp<FormItemRule>(),
|
|
||||||
/**
|
|
||||||
* picker cell 外部自定义样式
|
|
||||||
*/
|
|
||||||
customCellClass: makeStringProp(''),
|
|
||||||
/**
|
/**
|
||||||
* pickerView 外部自定义样式
|
* pickerView 外部自定义样式
|
||||||
*/
|
*/
|
||||||
customViewClass: makeStringProp(''),
|
customViewClass: makeStringProp(''),
|
||||||
/**
|
|
||||||
* label 外部自定义样式
|
|
||||||
*/
|
|
||||||
customLabelClass: makeStringProp(''),
|
|
||||||
/**
|
|
||||||
* value 外部自定义样式
|
|
||||||
*/
|
|
||||||
customValueClass: makeStringProp(''),
|
|
||||||
/**
|
/**
|
||||||
* 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
|
* 是否在手指松开时立即触发picker-view的 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,49 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view
|
<view :class="`wd-picker ${customClass}`" :style="customStyle">
|
||||||
:class="`wd-picker ${disabled ? 'is-disabled' : ''} ${size ? 'is-' + size : ''} ${cell.border.value ? 'is-border' : ''} ${
|
|
||||||
alignRight ? 'is-align-right' : ''
|
|
||||||
} ${error ? 'is-error' : ''} ${customClass}`"
|
|
||||||
:style="customStyle"
|
|
||||||
>
|
|
||||||
<!--文案-->
|
|
||||||
<view class="wd-picker__field" @click="showPopup">
|
|
||||||
<slot v-if="useDefaultSlot"></slot>
|
|
||||||
<view v-else :class="['wd-picker__cell', customCellClass]">
|
|
||||||
<view
|
|
||||||
v-if="label || useLabelSlot"
|
|
||||||
:class="`wd-picker__label ${customLabelClass} ${isRequired ? 'is-required' : ''}`"
|
|
||||||
:style="labelWidth ? 'min-width:' + labelWidth + ';max-width:' + labelWidth + ';' : ''"
|
|
||||||
>
|
|
||||||
<block v-if="label">{{ label }}</block>
|
|
||||||
<slot v-else name="label"></slot>
|
|
||||||
</view>
|
|
||||||
<view class="wd-picker__body">
|
|
||||||
<view class="wd-picker__value-wraper">
|
|
||||||
<view :class="`wd-picker__value ${customValueClass}`">
|
|
||||||
<template v-if="region">
|
|
||||||
<view v-if="isArray(showValue)">
|
|
||||||
<text :class="showValue[0] ? '' : 'wd-picker__placeholder'">
|
|
||||||
{{ showValue[0] ? showValue[0] : placeholder || translate('placeholder') }}
|
|
||||||
</text>
|
|
||||||
{{ translate('to') }}
|
|
||||||
<text :class="showValue[1] ? '' : 'wd-picker__placeholder'">
|
|
||||||
{{ showValue[1] ? showValue[1] : placeholder || translate('placeholder') }}
|
|
||||||
</text>
|
|
||||||
</view>
|
|
||||||
<view v-else class="wd-picker__placeholder">
|
|
||||||
{{ placeholder || translate('placeholder') }}
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
<view v-else :class="showValue ? '' : 'wd-picker__placeholder'">
|
|
||||||
{{ showValue ? showValue : placeholder || translate('placeholder') }}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<wd-icon v-if="!disabled && !readonly" custom-class="wd-picker__arrow" name="arrow-right" />
|
|
||||||
</view>
|
|
||||||
<view v-if="errorMessage" class="wd-picker__error-message">{{ errorMessage }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<!--弹出层,picker-view 在隐藏时修改值,会触发多次change事件,从而导致所有列选中第一项,因此picker在关闭时不隐藏 -->
|
<!--弹出层,picker-view 在隐藏时修改值,会触发多次change事件,从而导致所有列选中第一项,因此picker在关闭时不隐藏 -->
|
||||||
<wd-popup
|
<wd-popup
|
||||||
v-model="popupShow"
|
v-model="popupShow"
|
||||||
@ -154,17 +110,14 @@ export default {
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import wdPopup from '../wd-popup/wd-popup.vue'
|
import wdPopup from '../wd-popup/wd-popup.vue'
|
||||||
import wdDatetimePickerView from '../wd-datetime-picker-view/wd-datetime-picker-view.vue'
|
import wdDatetimePickerView from '../wd-datetime-picker-view/wd-datetime-picker-view.vue'
|
||||||
import { computed, getCurrentInstance, nextTick, onBeforeMount, onMounted, ref, watch } from 'vue'
|
import { getCurrentInstance, nextTick, onBeforeMount, onMounted, ref, watch } from 'vue'
|
||||||
import { deepClone, isArray, isDef, isEqual, isFunction, padZero } from '../common/util'
|
import { deepClone, isArray, isDef, isEqual, isFunction, padZero } from '../common/util'
|
||||||
import { useCell } from '../composables/useCell'
|
|
||||||
import {
|
import {
|
||||||
getPickerValue,
|
getPickerValue,
|
||||||
type DatetimePickerViewInstance,
|
type DatetimePickerViewInstance,
|
||||||
type DatetimePickerViewColumnFormatter,
|
type DatetimePickerViewColumnFormatter,
|
||||||
type DatetimePickerViewColumnType
|
type DatetimePickerViewColumnType
|
||||||
} from '../wd-datetime-picker-view/types'
|
} from '../wd-datetime-picker-view/types'
|
||||||
import { FORM_KEY, type FormItemRule } from '../wd-form/types'
|
|
||||||
import { useParent } from '../composables/useParent'
|
|
||||||
import { useTranslate } from '../composables/useTranslate'
|
import { useTranslate } from '../composables/useTranslate'
|
||||||
import { datetimePickerProps, type DatetimePickerExpose } from './types'
|
import { datetimePickerProps, type DatetimePickerExpose } from './types'
|
||||||
import { dayjs } from '../common/dayjs'
|
import { dayjs } from '../common/dayjs'
|
||||||
@ -177,7 +130,6 @@ const { translate } = useTranslate('datetime-picker')
|
|||||||
const datetimePickerView = ref<DatetimePickerViewInstance>()
|
const datetimePickerView = ref<DatetimePickerViewInstance>()
|
||||||
const datetimePickerView1 = ref<DatetimePickerViewInstance>()
|
const datetimePickerView1 = ref<DatetimePickerViewInstance>()
|
||||||
|
|
||||||
const showValue = ref<string | Date | Array<string | Date>>('')
|
|
||||||
const popupShow = ref<boolean>(false)
|
const popupShow = ref<boolean>(false)
|
||||||
const showStart = ref<boolean>(true)
|
const showStart = ref<boolean>(true)
|
||||||
const region = ref<boolean>(false)
|
const region = ref<boolean>(false)
|
||||||
@ -191,8 +143,6 @@ const hasConfirmed = ref<boolean>(false) // 判断用户是否点击了确认按
|
|||||||
const isLoading = ref<boolean>(false) // 加载
|
const isLoading = ref<boolean>(false) // 加载
|
||||||
const { proxy } = getCurrentInstance() as any
|
const { proxy } = getCurrentInstance() as any
|
||||||
|
|
||||||
const cell = useCell()
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(val, oldVal) => {
|
(val, oldVal) => {
|
||||||
@ -293,31 +243,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const { parent: form } = useParent(FORM_KEY)
|
|
||||||
|
|
||||||
// 表单校验错误信息
|
|
||||||
const errorMessage = computed(() => {
|
|
||||||
if (form && props.prop && form.errorMessages && form.errorMessages[props.prop]) {
|
|
||||||
return form.errorMessages[props.prop]
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 是否展示必填
|
|
||||||
const isRequired = computed(() => {
|
|
||||||
let formRequired = false
|
|
||||||
if (form && form.props.rules) {
|
|
||||||
const rules = form.props.rules
|
|
||||||
for (const key in rules) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(rules, key) && key === props.prop && Array.isArray(rules[key])) {
|
|
||||||
formRequired = rules[key].some((rule: FormItemRule) => rule.required)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props.required || props.rules.some((rule) => rule.required) || formRequired
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 自定义列项筛选规则,对每列单项进行禁用校验,最终返回传入PickerView的columns数组
|
* @description 自定义列项筛选规则,对每列单项进行禁用校验,最终返回传入PickerView的columns数组
|
||||||
* @param {Component} picker datetimePickerView对象
|
* @param {Component} picker datetimePickerView对象
|
||||||
@ -419,8 +344,6 @@ function close() {
|
|||||||
* @description 展示popup,小程序有个bug,在picker-view弹出时设置value,会触发change事件,而且会将picker-view的value多次触发change重置为第一项
|
* @description 展示popup,小程序有个bug,在picker-view弹出时设置value,会触发change事件,而且会将picker-view的value多次触发change重置为第一项
|
||||||
*/
|
*/
|
||||||
function showPopup() {
|
function showPopup() {
|
||||||
if (props.disabled || props.readonly) return
|
|
||||||
|
|
||||||
emit('open')
|
emit('open')
|
||||||
if (region.value) {
|
if (region.value) {
|
||||||
popupShow.value = true
|
popupShow.value = true
|
||||||
@ -536,7 +459,7 @@ function onPickEnd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleConfirm() {
|
function handleConfirm() {
|
||||||
if (props.loading || isLoading.value || props.disabled) {
|
if (props.loading || isLoading.value) {
|
||||||
popupShow.value = false
|
popupShow.value = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -585,19 +508,7 @@ function setShowValue(tab: boolean = false, isConfirm: boolean = false, beforeMo
|
|||||||
? (endInnerValue.value && getSelects('after')) || []
|
? (endInnerValue.value && getSelects('after')) || []
|
||||||
: (datetimePickerView1.value && datetimePickerView1.value.getSelects && datetimePickerView1.value.getSelects()) || []
|
: (datetimePickerView1.value && datetimePickerView1.value.getSelects && datetimePickerView1.value.getSelects()) || []
|
||||||
|
|
||||||
showValue.value = tab
|
|
||||||
? showValue.value
|
|
||||||
: [
|
|
||||||
(props.modelValue as (string | number)[])[0] || isConfirm ? defaultDisplayFormat(items as Record<string, any>[]) : '',
|
|
||||||
(props.modelValue as (string | number)[])[1] || isConfirm ? defaultDisplayFormat(endItems as Record<string, any>[]) : ''
|
|
||||||
]
|
|
||||||
showTabLabel.value = [defaultDisplayFormat(items as Record<string, any>[], true), defaultDisplayFormat(endItems as Record<string, any>[], true)]
|
showTabLabel.value = [defaultDisplayFormat(items as Record<string, any>[], true), defaultDisplayFormat(endItems as Record<string, any>[], true)]
|
||||||
} else {
|
|
||||||
const items = beforeMount
|
|
||||||
? (innerValue.value && getSelects('before')) || []
|
|
||||||
: (datetimePickerView.value && datetimePickerView.value.getSelects && datetimePickerView.value.getSelects()) || []
|
|
||||||
|
|
||||||
showValue.value = deepClone(props.modelValue || isConfirm ? defaultDisplayFormat(items as Record<string, any>[]) : '')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<!--
|
<!--
|
||||||
* @Author: weisheng
|
* @Author: weisheng
|
||||||
* @Date: 2023-12-14 11:21:58
|
* @Date: 2024-10-25 10:34:37
|
||||||
* @LastEditTime: 2024-03-15 21:29:33
|
* @LastEditTime: 2024-11-13 18:33:38
|
||||||
* @LastEditors: weisheng
|
* @LastEditors: weisheng
|
||||||
* @Description:
|
* @Description:
|
||||||
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-form-item/wd-form-item.vue
|
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-form-item\wd-form-item.vue
|
||||||
* 记得注释
|
* 记得注释
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@ -100,7 +100,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
width: $-input-cell-label-width;
|
width: $-input-cell-label-width;
|
||||||
color: $-cell-title-color;
|
color: $-cell-title-color;
|
||||||
margin-right: $-cell-padding;
|
margin-right: $-cell-vertical-padding;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-size: $-input-fs;
|
font-size: $-input-fs;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|||||||
@ -4,55 +4,11 @@
|
|||||||
|
|
||||||
.wot-theme-dark {
|
.wot-theme-dark {
|
||||||
@include b(picker) {
|
@include b(picker) {
|
||||||
@include when(border) {
|
|
||||||
.wd-picker__cell {
|
|
||||||
@include halfPixelBorder('top', $-cell-padding, $-dark-border-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(title) {
|
@include e(title) {
|
||||||
color: $-dark-color;
|
color: $-dark-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include e(label) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
@include e(value) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(placeholder) {
|
|
||||||
color: $-dark-color-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.wd-picker__arrow),
|
|
||||||
:deep(.wd-picker__clear) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(cell) {
|
|
||||||
background-color: $-dark-background2;
|
|
||||||
color: $-dark-color;
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-picker__value {
|
|
||||||
color: $-dark-color3;
|
|
||||||
}
|
|
||||||
.wd-picker__placeholder {
|
|
||||||
color: $-dark-color-gray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-picker__value {
|
|
||||||
color: $-dark-color3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wd-picker__placeholder {
|
|
||||||
color: $-dark-color-gray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(action) {
|
@include e(action) {
|
||||||
@include m(cancel) {
|
@include m(cancel) {
|
||||||
color: $-dark-color;
|
color: $-dark-color;
|
||||||
@ -70,119 +26,6 @@
|
|||||||
border-radius: 16px 16px 0px 0px;
|
border-radius: 16px 16px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include when(border) {
|
|
||||||
.wd-picker__cell {
|
|
||||||
@include halfPixelBorder('top', $-cell-padding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(large) {
|
|
||||||
.wd-picker__cell {
|
|
||||||
font-size: $-cell-title-fs-large;
|
|
||||||
}
|
|
||||||
:deep(.wd-picker__arrow),
|
|
||||||
:deep(.wd-picker__clear) {
|
|
||||||
font-size: $-cell-icon-size-large;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(error) {
|
|
||||||
.wd-picker__value,
|
|
||||||
:deep(.wd-picker__arrow) {
|
|
||||||
color: $-input-error-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(align-right) {
|
|
||||||
.wd-picker__value {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(cell) {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
padding: $-cell-wrapper-padding $-cell-padding;
|
|
||||||
align-items: flex-start;
|
|
||||||
background-color: $-color-white;
|
|
||||||
text-decoration: none;
|
|
||||||
color: $-cell-title-color;
|
|
||||||
font-size: $-cell-title-fs;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: $-cell-line-height;
|
|
||||||
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-picker__value {
|
|
||||||
color: $-input-disabled-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-picker__value {
|
|
||||||
color: $-picker-column-disabled-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(error-message){
|
|
||||||
color: $-form-item-error-message-color;
|
|
||||||
font-size: $-form-item-error-message-font-size;
|
|
||||||
line-height: $-form-item-error-message-line-height;
|
|
||||||
text-align: left;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(label) {
|
|
||||||
position: relative;
|
|
||||||
width: $-input-cell-label-width;
|
|
||||||
margin-right: $-cell-padding;
|
|
||||||
color: $-cell-title-color;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
@include when(required) {
|
|
||||||
padding-left: 12px;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 2px;
|
|
||||||
content: '*';
|
|
||||||
font-size: $-cell-required-size;
|
|
||||||
line-height: 1.1;
|
|
||||||
color: $-cell-required-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(value-wraper) {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(value) {
|
|
||||||
flex: 1;
|
|
||||||
margin-right: 10px;
|
|
||||||
color: $-cell-value-color;
|
|
||||||
|
|
||||||
@include when(ellipsis) {
|
|
||||||
@include lineEllipsis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(body) {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(placeholder) {
|
|
||||||
color: $-input-placeholder-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include edeep(arrow,clear) {
|
|
||||||
display: block;
|
|
||||||
font-size: $-cell-icon-size;
|
|
||||||
color: $-cell-arrow-color;
|
|
||||||
line-height: $-cell-line-height;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include edeep(clear){
|
|
||||||
color: $-cell-clear-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(wraper) {
|
@include e(wraper) {
|
||||||
padding-bottom: var(--window-bottom);
|
padding-bottom: var(--window-bottom);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,34 +5,10 @@ import type { FormItemRule } from '../wd-form/types'
|
|||||||
|
|
||||||
export const pickerProps = {
|
export const pickerProps = {
|
||||||
...baseProps,
|
...baseProps,
|
||||||
/**
|
|
||||||
* label 外部自定义样式
|
|
||||||
*/
|
|
||||||
customLabelClass: makeStringProp(''),
|
|
||||||
/**
|
|
||||||
* value 外部自定义样式
|
|
||||||
*/
|
|
||||||
customValueClass: makeStringProp(''),
|
|
||||||
/**
|
/**
|
||||||
* pickerView 外部自定义样式
|
* pickerView 外部自定义样式
|
||||||
*/
|
*/
|
||||||
customViewClass: makeStringProp(''),
|
customViewClass: makeStringProp(''),
|
||||||
/**
|
|
||||||
* 选择器左侧文案
|
|
||||||
*/
|
|
||||||
label: String,
|
|
||||||
/**
|
|
||||||
* 选择器占位符
|
|
||||||
*/
|
|
||||||
placeholder: String,
|
|
||||||
/**
|
|
||||||
* 是否禁用
|
|
||||||
*/
|
|
||||||
disabled: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 是否只读
|
|
||||||
*/
|
|
||||||
readonly: makeBooleanProp(false),
|
|
||||||
/**
|
/**
|
||||||
* 加载中
|
* 加载中
|
||||||
*/
|
*/
|
||||||
@ -54,34 +30,6 @@ export const pickerProps = {
|
|||||||
* 确认按钮文案
|
* 确认按钮文案
|
||||||
*/
|
*/
|
||||||
confirmButtonText: String,
|
confirmButtonText: String,
|
||||||
/**
|
|
||||||
* 是否必填
|
|
||||||
*/
|
|
||||||
required: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 尺寸
|
|
||||||
*/
|
|
||||||
size: String,
|
|
||||||
/**
|
|
||||||
* 标签宽度
|
|
||||||
*/
|
|
||||||
labelWidth: String,
|
|
||||||
/**
|
|
||||||
* 使用默认插槽
|
|
||||||
*/
|
|
||||||
useDefaultSlot: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 使用标签插槽
|
|
||||||
*/
|
|
||||||
useLabelSlot: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 错误状态
|
|
||||||
*/
|
|
||||||
error: makeBooleanProp(false),
|
|
||||||
/**
|
|
||||||
* 右对齐
|
|
||||||
*/
|
|
||||||
alignRight: makeBooleanProp(false),
|
|
||||||
/**
|
/**
|
||||||
* 确定前校验函数,接收 (value, resolve, picker) 参数,通过 resolve 继续执行 picker,resolve 接收1个boolean参数
|
* 确定前校验函数,接收 (value, resolve, picker) 参数,通过 resolve 继续执行 picker,resolve 接收1个boolean参数
|
||||||
*/
|
*/
|
||||||
@ -94,10 +42,6 @@ export const pickerProps = {
|
|||||||
* 底部安全区域内
|
* 底部安全区域内
|
||||||
*/
|
*/
|
||||||
safeAreaInsetBottom: makeBooleanProp(true),
|
safeAreaInsetBottom: makeBooleanProp(true),
|
||||||
/**
|
|
||||||
* 文本溢出显示省略号
|
|
||||||
*/
|
|
||||||
ellipsis: makeBooleanProp(false),
|
|
||||||
/**
|
/**
|
||||||
* 选项总高度
|
* 选项总高度
|
||||||
*/
|
*/
|
||||||
@ -136,22 +80,10 @@ export const pickerProps = {
|
|||||||
* 自定义层级
|
* 自定义层级
|
||||||
*/
|
*/
|
||||||
zIndex: makeNumberProp(15),
|
zIndex: makeNumberProp(15),
|
||||||
/**
|
|
||||||
* 表单域 model 字段名,在使用表单校验功能的情况下,该属性是必填的
|
|
||||||
*/
|
|
||||||
prop: String,
|
|
||||||
/**
|
|
||||||
* 表单验证规则,结合wd-form组件使用
|
|
||||||
*/
|
|
||||||
rules: makeArrayProp<FormItemRule>(),
|
|
||||||
/**
|
/**
|
||||||
* 是否在手指松开时立即触发 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
|
* 是否在手指松开时立即触发 change 事件。若不开启则会在滚动动画结束后触发 change 事件,1.2.25版本起提供,仅微信小程序和支付宝小程序支持。
|
||||||
*/
|
*/
|
||||||
immediateChange: makeBooleanProp(false),
|
immediateChange: makeBooleanProp(false)
|
||||||
/**
|
|
||||||
* 显示清空按钮
|
|
||||||
*/
|
|
||||||
clearable: makeBooleanProp(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PickerProps = ExtractPropTypes<typeof pickerProps>
|
export type PickerProps = ExtractPropTypes<typeof pickerProps>
|
||||||
|
|||||||
@ -1,35 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view
|
<view :class="`wd-picker ${customClass}`" :style="customStyle">
|
||||||
:class="`wd-picker ${disabled ? 'is-disabled' : ''} ${size ? 'is-' + size : ''} ${cell.border.value ? 'is-border' : ''} ${
|
|
||||||
alignRight ? 'is-align-right' : ''
|
|
||||||
} ${error ? 'is-error' : ''} ${customClass}`"
|
|
||||||
:style="customStyle"
|
|
||||||
>
|
|
||||||
<view class="wd-picker__field" @click="showPopup">
|
|
||||||
<slot v-if="useDefaultSlot"></slot>
|
|
||||||
<view v-else class="wd-picker__cell">
|
|
||||||
<view
|
|
||||||
v-if="label || useLabelSlot"
|
|
||||||
:class="`wd-picker__label ${customLabelClass} ${isRequired ? 'is-required' : ''}`"
|
|
||||||
:style="labelWidth ? 'min-width:' + labelWidth + ';max-width:' + labelWidth + ';' : ''"
|
|
||||||
>
|
|
||||||
<template v-if="label">{{ label }}</template>
|
|
||||||
<slot v-else name="label"></slot>
|
|
||||||
</view>
|
|
||||||
<view class="wd-picker__body">
|
|
||||||
<view class="wd-picker__value-wraper">
|
|
||||||
<view :class="`wd-picker__value ${ellipsis && 'is-ellipsis'} ${customValueClass} ${showValue ? '' : 'wd-picker__placeholder'}`">
|
|
||||||
{{ showValue ? showValue : placeholder || translate('placeholder') }}
|
|
||||||
</view>
|
|
||||||
<wd-icon v-if="showArrow" custom-class="wd-picker__arrow" name="arrow-right" />
|
|
||||||
<view v-else-if="showClear" @click.stop="handleClear">
|
|
||||||
<wd-icon custom-class="wd-picker__clear" name="error-fill" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view v-if="errorMessage" class="wd-picker__error-message">{{ errorMessage }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<wd-popup
|
<wd-popup
|
||||||
v-model="popupShow"
|
v-model="popupShow"
|
||||||
position="bottom"
|
position="bottom"
|
||||||
@ -83,15 +53,11 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import wdIcon from '../wd-icon/wd-icon.vue'
|
|
||||||
import wdPopup from '../wd-popup/wd-popup.vue'
|
import wdPopup from '../wd-popup/wd-popup.vue'
|
||||||
import wdPickerView from '../wd-picker-view/wd-picker-view.vue'
|
import wdPickerView from '../wd-picker-view/wd-picker-view.vue'
|
||||||
import { getCurrentInstance, onBeforeMount, ref, watch, computed, onMounted, nextTick } from 'vue'
|
import { getCurrentInstance, onBeforeMount, ref, watch, computed, onMounted, nextTick } from 'vue'
|
||||||
import { deepClone, defaultDisplayFormat, getType, isArray, isDef, isFunction } from '../common/util'
|
import { deepClone, getType, isArray, isDef, isFunction } from '../common/util'
|
||||||
import { useCell } from '../composables/useCell'
|
|
||||||
import { type ColumnItem, formatArray, type PickerViewInstance } from '../wd-picker-view/types'
|
import { type ColumnItem, formatArray, type PickerViewInstance } from '../wd-picker-view/types'
|
||||||
import { FORM_KEY, type FormItemRule } from '../wd-form/types'
|
|
||||||
import { useParent } from '../composables/useParent'
|
|
||||||
import { useTranslate } from '../composables/useTranslate'
|
import { useTranslate } from '../composables/useTranslate'
|
||||||
import { pickerProps, type PickerExpose } from './types'
|
import { pickerProps, type PickerExpose } from './types'
|
||||||
const { translate } = useTranslate('picker')
|
const { translate } = useTranslate('picker')
|
||||||
@ -100,14 +66,12 @@ const props = defineProps(pickerProps)
|
|||||||
const emit = defineEmits(['confirm', 'open', 'cancel', 'clear', 'update:modelValue'])
|
const emit = defineEmits(['confirm', 'open', 'cancel', 'clear', 'update:modelValue'])
|
||||||
|
|
||||||
const pickerViewWd = ref<PickerViewInstance | null>(null)
|
const pickerViewWd = ref<PickerViewInstance | null>(null)
|
||||||
const cell = useCell()
|
|
||||||
|
|
||||||
const innerLoading = ref<boolean>(false) // 内部控制是否loading
|
const innerLoading = ref<boolean>(false) // 内部控制是否loading
|
||||||
|
|
||||||
// 弹出层是否显示
|
// 弹出层是否显示
|
||||||
const popupShow = ref<boolean>(false)
|
const popupShow = ref<boolean>(false)
|
||||||
// 选定后展示的选中项
|
// 选定后展示的选中项
|
||||||
const showValue = ref<string>('')
|
|
||||||
const pickerValue = ref<string | number | boolean | string[] | number[] | boolean[]>('')
|
const pickerValue = ref<string | number | boolean | string[] | number[] | boolean[]>('')
|
||||||
const displayColumns = ref<Array<string | number | ColumnItem | Array<string | number | ColumnItem>>>([]) // 传入 pickerView 的columns
|
const displayColumns = ref<Array<string | number | ColumnItem | Array<string | number | ColumnItem>>>([]) // 传入 pickerView 的columns
|
||||||
const resetColumns = ref<Array<string | number | ColumnItem | Array<string | number | ColumnItem>>>([]) // 保存之前的 columns,当取消时,将数据源回滚,避免多级联动数据源不正确的情况
|
const resetColumns = ref<Array<string | number | ColumnItem | Array<string | number | ColumnItem>>>([]) // 保存之前的 columns,当取消时,将数据源回滚,避免多级联动数据源不正确的情况
|
||||||
@ -174,31 +138,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const { parent: form } = useParent(FORM_KEY)
|
|
||||||
|
|
||||||
// 表单校验错误信息
|
|
||||||
const errorMessage = computed(() => {
|
|
||||||
if (form && props.prop && form.errorMessages && form.errorMessages[props.prop]) {
|
|
||||||
return form.errorMessages[props.prop]
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 是否展示必填
|
|
||||||
const isRequired = computed(() => {
|
|
||||||
let formRequired = false
|
|
||||||
if (form && form.props.rules) {
|
|
||||||
const rules = form.props.rules
|
|
||||||
for (const key in rules) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(rules, key) && key === props.prop && Array.isArray(rules[key])) {
|
|
||||||
formRequired = rules[key].some((rule: FormItemRule) => rule.required)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props.required || props.rules.some((rule) => rule.required) || formRequired
|
|
||||||
})
|
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as any
|
const { proxy } = getCurrentInstance() as any
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -219,13 +158,13 @@ function handleShowValueUpdate(value: string | number | Array<string | number>)
|
|||||||
if ((isArray(value) && value.length > 0) || (isDef(value) && !isArray(value) && value !== '')) {
|
if ((isArray(value) && value.length > 0) || (isDef(value) && !isArray(value) && value !== '')) {
|
||||||
if (pickerViewWd.value) {
|
if (pickerViewWd.value) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
setShowValue(pickerViewWd.value!.getSelects())
|
// setShowValue(pickerViewWd.value!.getSelects())
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
setShowValue(getSelects(value)!)
|
// setShowValue(getSelects(value)!)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showValue.value = ''
|
// showValue.value = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,8 +223,6 @@ function close() {
|
|||||||
* 展示popup
|
* 展示popup
|
||||||
*/
|
*/
|
||||||
function showPopup() {
|
function showPopup() {
|
||||||
if (props.disabled || props.readonly) return
|
|
||||||
|
|
||||||
emit('open')
|
emit('open')
|
||||||
popupShow.value = true
|
popupShow.value = true
|
||||||
pickerValue.value = props.modelValue
|
pickerValue.value = props.modelValue
|
||||||
@ -329,7 +266,7 @@ function onConfirm() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function handleConfirm() {
|
function handleConfirm() {
|
||||||
if (isLoading.value || props.disabled) {
|
if (isLoading.value) {
|
||||||
popupShow.value = false
|
popupShow.value = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -342,7 +279,7 @@ function handleConfirm() {
|
|||||||
resetColumns.value = deepClone(columns)
|
resetColumns.value = deepClone(columns)
|
||||||
emit('update:modelValue', values)
|
emit('update:modelValue', values)
|
||||||
|
|
||||||
setShowValue(selects)
|
// setShowValue(selects)
|
||||||
emit('confirm', {
|
emit('confirm', {
|
||||||
value: values,
|
value: values,
|
||||||
selectedItems: selects
|
selectedItems: selects
|
||||||
@ -355,18 +292,9 @@ function handleConfirm() {
|
|||||||
function pickerViewChange({ value }: any) {
|
function pickerViewChange({ value }: any) {
|
||||||
pickerValue.value = value
|
pickerValue.value = value
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 设置展示值
|
|
||||||
* @param items
|
|
||||||
*/
|
|
||||||
function setShowValue(items: ColumnItem | ColumnItem[]) {
|
|
||||||
// 避免值为空时调用自定义展示函数
|
|
||||||
if ((isArray(items) && !items.length) || !items) return
|
|
||||||
|
|
||||||
const { valueKey, labelKey } = props
|
|
||||||
showValue.value = (props.displayFormat || defaultDisplayFormat)(items, { valueKey, labelKey })
|
|
||||||
}
|
|
||||||
function noop() {}
|
function noop() {}
|
||||||
|
|
||||||
function onPickStart() {
|
function onPickStart() {
|
||||||
isPicking.value = true
|
isPicking.value = true
|
||||||
}
|
}
|
||||||
@ -387,22 +315,6 @@ function setLoading(loading: boolean) {
|
|||||||
innerLoading.value = loading
|
innerLoading.value = loading
|
||||||
}
|
}
|
||||||
|
|
||||||
// 是否展示清除按钮
|
|
||||||
const showClear = computed(() => {
|
|
||||||
return props.clearable && !props.disabled && !props.readonly && showValue.value.length
|
|
||||||
})
|
|
||||||
|
|
||||||
function handleClear() {
|
|
||||||
const clearValue = isArray(pickerValue.value) ? [] : ''
|
|
||||||
emit('update:modelValue', clearValue)
|
|
||||||
emit('clear')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否展示箭头
|
|
||||||
const showArrow = computed(() => {
|
|
||||||
return !props.disabled && !props.readonly && !showClear.value
|
|
||||||
})
|
|
||||||
|
|
||||||
defineExpose<PickerExpose>({
|
defineExpose<PickerExpose>({
|
||||||
close,
|
close,
|
||||||
open,
|
open,
|
||||||
|
|||||||
@ -37,10 +37,13 @@
|
|||||||
font-size: $-progress-icon-fs;
|
font-size: $-progress-icon-fs;
|
||||||
|
|
||||||
@include when(danger) {
|
@include when(danger) {
|
||||||
background: $-progress-linear-danger-color;
|
background: $-progress-danger-color;
|
||||||
}
|
}
|
||||||
@include when(success) {
|
@include when(success) {
|
||||||
background: $-progress-linear-success-color;
|
background: $-progress-success-color;
|
||||||
|
}
|
||||||
|
@include when(warning) {
|
||||||
|
background: $-progress-warning-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@include edeep(label) {
|
@include edeep(label) {
|
||||||
@ -58,5 +61,8 @@
|
|||||||
@include when(success) {
|
@include when(success) {
|
||||||
color: $-progress-success-color;
|
color: $-progress-success-color;
|
||||||
}
|
}
|
||||||
|
@include when(warning) {
|
||||||
|
color: $-progress-warning-color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,16 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: weisheng
|
* @Author: weisheng
|
||||||
* @Date: 2024-03-15 20:40:34
|
* @Date: 2024-03-15 20:40:34
|
||||||
* @LastEditTime: 2024-03-18 15:32:11
|
* @LastEditTime: 2024-11-13 21:52:52
|
||||||
* @LastEditors: weisheng
|
* @LastEditors: weisheng
|
||||||
* @Description:
|
* @Description:
|
||||||
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-progress\types.ts
|
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-progress/types.ts
|
||||||
* 记得注释
|
* 记得注释
|
||||||
*/
|
*/
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { baseProps, makeBooleanProp, makeNumberProp } from '../common/props'
|
import { baseProps, makeBooleanProp, makeNumberProp } from '../common/props'
|
||||||
|
|
||||||
export type ProgressStatus = 'success' | 'danger' // 状态类型
|
export type ProgressStatus = 'success' | 'danger' | 'warning' // 状态类型
|
||||||
|
|
||||||
|
export type ProgressColor = {
|
||||||
|
color: string // 颜色
|
||||||
|
percentage: number // 百分比
|
||||||
|
}
|
||||||
|
|
||||||
export const progressProps = {
|
export const progressProps = {
|
||||||
...baseProps,
|
...baseProps,
|
||||||
@ -26,8 +31,8 @@ export const progressProps = {
|
|||||||
* 进度条颜色
|
* 进度条颜色
|
||||||
*/
|
*/
|
||||||
color: {
|
color: {
|
||||||
type: [String, Array, Object] as PropType<string | string[] | Record<string, any>[]>,
|
type: [String, Array, Object] as PropType<string | string[] | ProgressColor[]>,
|
||||||
default: 'linear-gradient(315deg, rgba(81,124,240,1) 0%,rgba(118,158,245,1) 100%)'
|
default: ''
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 进度增加1%所需毫秒数
|
* 进度增加1%所需毫秒数
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
<wd-icon
|
<wd-icon
|
||||||
v-else-if="status"
|
v-else-if="status"
|
||||||
:custom-class="`wd-progress__label wd-progress__icon ${progressClass}`"
|
:custom-class="`wd-progress__label wd-progress__icon ${progressClass}`"
|
||||||
:name="status == 'danger' ? 'close-outline' : 'check-outline'"
|
:name="statusIcon"
|
||||||
:color="typeof color === 'string' ? color : ''"
|
:color="typeof color === 'string' ? color : ''"
|
||||||
></wd-icon>
|
></wd-icon>
|
||||||
</view>
|
</view>
|
||||||
@ -28,9 +28,9 @@ export default {
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import wdIcon from '../wd-icon/wd-icon.vue'
|
import wdIcon from '../wd-icon/wd-icon.vue'
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, watch, type CSSProperties } from 'vue'
|
||||||
import { checkNumRange, isArray, objToStyle } from '../common/util'
|
import { checkNumRange, isArray, isObj, objToStyle } from '../common/util'
|
||||||
import { progressProps } from './types'
|
import { progressProps, type ProgressColor } from './types'
|
||||||
|
|
||||||
const props = defineProps(progressProps)
|
const props = defineProps(progressProps)
|
||||||
// 进度条展示的颜色
|
// 进度条展示的颜色
|
||||||
@ -44,14 +44,34 @@ const progressClass = ref<string>('')
|
|||||||
let timer: NodeJS.Timeout | null = null // 定时器
|
let timer: NodeJS.Timeout | null = null // 定时器
|
||||||
|
|
||||||
const rootStyle = computed(() => {
|
const rootStyle = computed(() => {
|
||||||
const style: Record<string, string | number> = {
|
const style: CSSProperties = {
|
||||||
background: showColor.value,
|
|
||||||
width: showPercent.value + '%',
|
width: showPercent.value + '%',
|
||||||
'transition-duration': changeCount.value * props.duration * 0.001 + 's'
|
'transition-duration': changeCount.value * props.duration * 0.001 + 's'
|
||||||
}
|
}
|
||||||
|
if (showColor.value) {
|
||||||
|
style.background = showColor.value
|
||||||
|
}
|
||||||
return objToStyle(style)
|
return objToStyle(style)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const statusIcon = computed(() => {
|
||||||
|
let icon: string = ''
|
||||||
|
switch (props.status) {
|
||||||
|
case 'danger':
|
||||||
|
icon = 'close-outline'
|
||||||
|
break
|
||||||
|
case 'success':
|
||||||
|
icon = 'check-outline'
|
||||||
|
break
|
||||||
|
case 'warning':
|
||||||
|
icon = 'warn-bold'
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return icon
|
||||||
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.percentage,
|
() => props.percentage,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
@ -129,22 +149,15 @@ function update(targetPercent: number, color: string) {
|
|||||||
* @description 控制进度条的进度和每段的颜色
|
* @description 控制进度条的进度和每段的颜色
|
||||||
*/
|
*/
|
||||||
function controlProgress() {
|
function controlProgress() {
|
||||||
const {
|
const { percentage, color } = props
|
||||||
// 目标百分比
|
|
||||||
percentage,
|
|
||||||
// 传入的color数组
|
|
||||||
color
|
|
||||||
} = props
|
|
||||||
// 锁
|
|
||||||
if (showPercent.value === percentage || !percentage) return
|
if (showPercent.value === percentage || !percentage) return
|
||||||
/**
|
/**
|
||||||
* 数组边界安全判断
|
* 数组边界安全判断
|
||||||
*/
|
*/
|
||||||
let colorArray: string[] | Record<string, any>[] = (isArray(color) ? color : [color]) as string[] | Record<string, any>[]
|
let colorArray: string[] | ProgressColor[] = (isArray(color) ? color : [color]) as string[] | ProgressColor[]
|
||||||
if (colorArray.length === 0) throw Error('The colorArray is empty')
|
if (colorArray.length === 0) throw Error('The colorArray is empty')
|
||||||
const isStrArray = (colorArray as any).every((item: any) => typeof item === 'string')
|
const isStrArray = colorArray.every((item) => typeof item === 'string')
|
||||||
// eslint-disable-next-line no-prototype-builtins
|
const isObjArray = colorArray.every((color) => isObj(color))
|
||||||
const isObjArray = (colorArray as any).every((color: any) => color.hasOwnProperty('color') && color.hasOwnProperty('percentage'))
|
|
||||||
if (!isStrArray && !isObjArray) {
|
if (!isStrArray && !isObjArray) {
|
||||||
throw Error('Color must be String or Object with color and percentage')
|
throw Error('Color must be String or Object with color and percentage')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,145 +3,12 @@
|
|||||||
|
|
||||||
.wot-theme-dark {
|
.wot-theme-dark {
|
||||||
@include b(select-picker) {
|
@include b(select-picker) {
|
||||||
@include when(border) {
|
|
||||||
.wd-select-picker__cell {
|
|
||||||
@include halfPixelBorder('top', $-cell-padding, $-dark-border-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(cell) {
|
|
||||||
background-color: $-dark-background2;
|
|
||||||
color: $-dark-color;
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-select-picker__value {
|
|
||||||
color: $-dark-color3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(label) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
@include e(value) {
|
|
||||||
color: $-dark-color;
|
|
||||||
@include m(placeholder) {
|
|
||||||
color: $-dark-color-gray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.wd-select-picker__arrow),
|
|
||||||
:deep(.wd-select-picker__close),
|
|
||||||
:deep(.wd-select-picker__clear) {
|
|
||||||
color: $-dark-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@include b(select-picker) {
|
@include b(select-picker) {
|
||||||
@include when(border) {
|
|
||||||
.wd-select-picker__cell {
|
|
||||||
@include halfPixelBorder('top', $-cell-padding);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(cell) {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
padding: $-cell-wrapper-padding $-cell-padding;
|
|
||||||
align-items: flex-start;
|
|
||||||
background-color: $-color-white;
|
|
||||||
text-decoration: none;
|
|
||||||
color: $-cell-title-color;
|
|
||||||
font-size: $-cell-title-fs;
|
|
||||||
overflow: hidden;
|
|
||||||
line-height: $-cell-line-height;
|
|
||||||
}
|
|
||||||
@include e(cell) {
|
|
||||||
@include when(disabled) {
|
|
||||||
.wd-select-picker__value {
|
|
||||||
color: $-input-disabled-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(align-right) {
|
|
||||||
.wd-select-picker__value {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(error) {
|
|
||||||
.wd-select-picker__value {
|
|
||||||
color: $-input-error-color;
|
|
||||||
}
|
|
||||||
:deep(.wd-select-picker__arrow) {
|
|
||||||
color: $-input-error-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include when(large) {
|
|
||||||
font-size: $-cell-title-fs-large;
|
|
||||||
|
|
||||||
:deep(.wd-select-picker__arrow),
|
|
||||||
:deep(.wd-select-picker__clear) {
|
|
||||||
font-size: $-cell-icon-size-large;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(error-message){
|
|
||||||
color: $-form-item-error-message-color;
|
|
||||||
font-size: $-form-item-error-message-font-size;
|
|
||||||
line-height: $-form-item-error-message-line-height;
|
|
||||||
text-align: left;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
@include e(label) {
|
|
||||||
position: relative;
|
|
||||||
width: $-input-cell-label-width;
|
|
||||||
color: $-cell-title-color;
|
|
||||||
margin-right: $-cell-padding;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
@include when(required) {
|
|
||||||
padding-left: 12px;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 2px;
|
|
||||||
content: '*';
|
|
||||||
font-size: $-cell-required-size;
|
|
||||||
line-height: 1.1;
|
|
||||||
color: $-cell-required-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(value-wraper) {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
@include e(value) {
|
|
||||||
flex: 1;
|
|
||||||
margin-right: 10px;
|
|
||||||
color: $-cell-value-color;
|
|
||||||
|
|
||||||
@include when(ellipsis) {
|
|
||||||
@include lineEllipsis;
|
|
||||||
}
|
|
||||||
@include m(placeholder) {
|
|
||||||
color: $-input-placeholder-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include e(body) {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
@include edeep(arrow, clear) {
|
|
||||||
display: block;
|
|
||||||
font-size: $-cell-icon-size;
|
|
||||||
color: $-cell-arrow-color;
|
|
||||||
line-height: $-cell-line-height;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include edeep(clear) {
|
|
||||||
color: $-cell-clear-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include e(loading) {
|
@include e(loading) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -1,40 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<view :class="`wd-select-picker ${cell.border.value ? 'is-border' : ''} ${customClass}`" :style="customStyle">
|
<view :class="`wd-select-picker ${customClass}`" :style="customStyle">
|
||||||
<view class="wd-select-picker__field" @click="open">
|
|
||||||
<slot v-if="useDefaultSlot"></slot>
|
|
||||||
<view
|
|
||||||
v-else
|
|
||||||
:class="`wd-select-picker__cell ${disabled && 'is-disabled'} ${readonly && 'is-readonly'} ${alignRight && 'is-align-right'} ${
|
|
||||||
error && 'is-error'
|
|
||||||
} ${size && 'is-' + size}`"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
v-if="label || useLabelSlot"
|
|
||||||
:class="`wd-select-picker__label ${isRequired && 'is-required'} ${customLabelClass}`"
|
|
||||||
:style="labelWidth ? 'min-width:' + labelWidth + ';max-width:' + labelWidth + ';' : ''"
|
|
||||||
>
|
|
||||||
<block v-if="label">{{ label }}</block>
|
|
||||||
<slot v-else name="label"></slot>
|
|
||||||
</view>
|
|
||||||
<view class="wd-select-picker__body">
|
|
||||||
<view class="wd-select-picker__value-wraper">
|
|
||||||
<view
|
|
||||||
:class="`wd-select-picker__value ${ellipsis && 'is-ellipsis'} ${customValueClass} ${
|
|
||||||
showValue ? '' : 'wd-select-picker__value--placeholder'
|
|
||||||
}`"
|
|
||||||
>
|
|
||||||
{{ showValue || placeholder || translate('placeholder') }}
|
|
||||||
</view>
|
|
||||||
<wd-icon v-if="showArrow" custom-class="wd-select-picker__arrow" name="arrow-right" />
|
|
||||||
<view v-else-if="showClear" @click.stop="handleClear">
|
|
||||||
<wd-icon custom-class="wd-select-picker__clear" name="error-fill" />
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view v-if="errorMessage" class="wd-select-picker__error-message">{{ errorMessage }}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<wd-action-sheet
|
<wd-action-sheet
|
||||||
v-model="pickerShow"
|
v-model="pickerShow"
|
||||||
:duration="250"
|
:duration="250"
|
||||||
@ -127,10 +92,7 @@ import wdButton from '../wd-button/wd-button.vue'
|
|||||||
import wdLoading from '../wd-loading/wd-loading.vue'
|
import wdLoading from '../wd-loading/wd-loading.vue'
|
||||||
|
|
||||||
import { getCurrentInstance, onBeforeMount, ref, watch, nextTick, computed } from 'vue'
|
import { getCurrentInstance, onBeforeMount, ref, watch, nextTick, computed } from 'vue'
|
||||||
import { useCell } from '../composables/useCell'
|
|
||||||
import { getRect, isArray, isDef, isFunction, requestAnimationFrame } from '../common/util'
|
import { getRect, isArray, isDef, isFunction, requestAnimationFrame } from '../common/util'
|
||||||
import { useParent } from '../composables/useParent'
|
|
||||||
import { FORM_KEY, type FormItemRule } from '../wd-form/types'
|
|
||||||
import { useTranslate } from '../composables/useTranslate'
|
import { useTranslate } from '../composables/useTranslate'
|
||||||
import { selectPickerProps, type SelectPickerExpose } from './types'
|
import { selectPickerProps, type SelectPickerExpose } from './types'
|
||||||
|
|
||||||
@ -146,34 +108,6 @@ const lastSelectList = ref<Array<number | boolean | string> | number | boolean |
|
|||||||
const filterVal = ref<string>('')
|
const filterVal = ref<string>('')
|
||||||
const filterColumns = ref<Array<Record<string, any>>>([])
|
const filterColumns = ref<Array<Record<string, any>>>([])
|
||||||
const scrollTop = ref<number>(0) // 滚动位置
|
const scrollTop = ref<number>(0) // 滚动位置
|
||||||
const cell = useCell()
|
|
||||||
|
|
||||||
const showValue = computed(() => {
|
|
||||||
const value = valueFormat(props.modelValue)
|
|
||||||
let showValueTemp: string = ''
|
|
||||||
|
|
||||||
if (props.displayFormat) {
|
|
||||||
showValueTemp = props.displayFormat(value, props.columns)
|
|
||||||
} else {
|
|
||||||
const { type, labelKey } = props
|
|
||||||
if (type === 'checkbox') {
|
|
||||||
const selectedItems = (isArray(value) ? value : []).map((item) => {
|
|
||||||
return getSelectedItem(item)
|
|
||||||
})
|
|
||||||
showValueTemp = selectedItems
|
|
||||||
.map((item) => {
|
|
||||||
return item[labelKey]
|
|
||||||
})
|
|
||||||
.join(', ')
|
|
||||||
} else if (type === 'radio') {
|
|
||||||
const selectedItem = getSelectedItem(value as string | number | boolean)
|
|
||||||
showValueTemp = selectedItem[labelKey]
|
|
||||||
} else {
|
|
||||||
showValueTemp = value as string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return showValueTemp
|
|
||||||
})
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
@ -229,31 +163,6 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const { parent: form } = useParent(FORM_KEY)
|
|
||||||
|
|
||||||
// 表单校验错误信息
|
|
||||||
const errorMessage = computed(() => {
|
|
||||||
if (form && props.prop && form.errorMessages && form.errorMessages[props.prop]) {
|
|
||||||
return form.errorMessages[props.prop]
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 是否展示必填
|
|
||||||
const isRequired = computed(() => {
|
|
||||||
let formRequired = false
|
|
||||||
if (form && form.props.rules) {
|
|
||||||
const rules = form.props.rules
|
|
||||||
for (const key in rules) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(rules, key) && key === props.prop && Array.isArray(rules[key])) {
|
|
||||||
formRequired = rules[key].some((rule: FormItemRule) => rule.required)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return props.required || props.rules.some((rule) => rule.required) || formRequired
|
|
||||||
})
|
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
selectList.value = valueFormat(props.modelValue)
|
selectList.value = valueFormat(props.modelValue)
|
||||||
filterColumns.value = props.columns
|
filterColumns.value = props.columns
|
||||||
@ -429,21 +338,6 @@ const showConfirm = computed(() => {
|
|||||||
return (props.type === 'radio' && props.showConfirm) || props.type === 'checkbox'
|
return (props.type === 'radio' && props.showConfirm) || props.type === 'checkbox'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 是否展示清除按钮
|
|
||||||
const showClear = computed(() => {
|
|
||||||
return props.clearable && !props.disabled && !props.readonly && showValue.value.length
|
|
||||||
})
|
|
||||||
|
|
||||||
function handleClear() {
|
|
||||||
emit('update:modelValue', props.type === 'checkbox' ? [] : '')
|
|
||||||
emit('clear')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否展示箭头
|
|
||||||
const showArrow = computed(() => {
|
|
||||||
return !props.disabled && !props.readonly && !showClear.value
|
|
||||||
})
|
|
||||||
|
|
||||||
defineExpose<SelectPickerExpose>({
|
defineExpose<SelectPickerExpose>({
|
||||||
close,
|
close,
|
||||||
open
|
open
|
||||||
|
|||||||
@ -98,7 +98,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
width: $-input-cell-label-width;
|
width: $-input-cell-label-width;
|
||||||
color: $-cell-title-color;
|
color: $-cell-title-color;
|
||||||
margin-right: $-cell-padding;
|
margin-right: $-cell-vertical-padding;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-size: $-textarea-fs;
|
font-size: $-textarea-fs;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user