升级依赖

This commit is contained in:
xiangheng
2024-06-05 17:53:40 +08:00
parent facd51c147
commit 593b8e820d
47 changed files with 923 additions and 335 deletions

View File

@@ -1,3 +1,5 @@
## 1.0.142024-05-31
1. 修复设置maxDate后存在选择不准确的BUG
## 1.0.132024-03-22
1. 修复VUE3中出现的BUG
## 1.0.122023-11-27

View File

@@ -78,7 +78,9 @@
},
watch: {
propsChange() {
this.init()
uni.$uv.sleep(100).then(res=>{
this.init()
})
}
},
computed: {

View File

@@ -1,7 +1,7 @@
{
"id": "uv-datetime-picker",
"displayName": "uv-datetime-picker 时间选择器 全面兼容vue3+2、app、h5、小程序等多端",
"version": "1.0.13",
"version": "1.0.14",
"description": "时间选择器组件用于时间日期,主要用于年月日时分的选择,具体选择的精确度由参数控制。",
"keywords": [
"datetime-picker",
@@ -43,7 +43,8 @@
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
"aliyun": "y",
"alipay": "n"
},
"client": {
"Vue": {

View File

@@ -1,29 +1,101 @@
## 1.2.192024-05-01
### [1.2.19](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.18...v1.2.19) (2024-05-01)
### ✨ Features | 新功能
*`Slider`组件`min`值允许负数 ([9e7c8d3](https://github.com/Moonofweisheng/wot-design-uni/commit/9e7c8d33eb2c0fccc44f465ed3b28d2cd81efa2d)), closes [#266](https://github.com/Moonofweisheng/wot-design-uni/issues/266)
* ✨ fab添加draggable属性 ([#259](https://github.com/Moonofweisheng/wot-design-uni/issues/259)) ([5e0cd6c](https://github.com/Moonofweisheng/wot-design-uni/commit/5e0cd6caa2296a44a3dc1b3d33033d4cc91d01b9))
* ✨ table组件添加index参数 ([2161705](https://github.com/Moonofweisheng/wot-design-uni/commit/2161705a2f868f874b89ee28b6029677854a7741))
## 1.2.242024-06-04
### [1.2.24](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.23...v1.2.24) (2024-06-03)
### Bug Fixes | Bug 修复
* 修复`slider`组件`step`属性无效问题 ([50133b9](https://github.com/Moonofweisheng/wot-design-uni/commit/50133b9e5e2a18aace8cbf9eb7570579cc563f1d)), closes [#269](https://github.com/Moonofweisheng/wot-design-uni/issues/269)
* 修复Cell组件title文字对齐方式受外部影响的问题 ([caf66b6](https://github.com/Moonofweisheng/wot-design-uni/commit/caf66b6beeb236a9295cf0d8ec250557dc19e54e)), closes [#282](https://github.com/Moonofweisheng/wot-design-uni/issues/282)
* 修复SelectPicker无默认值时仍会查找选择项节点的问题 ([130c438](https://github.com/Moonofweisheng/wot-design-uni/commit/130c4383dc862e190b96bc3670a852a4cce3e629)), closes [#281](https://github.com/Moonofweisheng/wot-design-uni/issues/281)
* 修复Slider组件max和min变化时滑块和进度条未更新的问题 ([#276](https://github.com/Moonofweisheng/wot-design-uni/issues/276)) ([69303b5](https://github.com/Moonofweisheng/wot-design-uni/commit/69303b52077bd268e3563fa9096e91530bb978c5))
### Documentation | 文档
* 补充Table组件关于Events的介绍 ([6760317](https://github.com/Moonofweisheng/wot-design-uni/commit/676031781b189a3a89dba9e57cb989c06999091a)), closes [#260](https://github.com/Moonofweisheng/wot-design-uni/issues/260)
* 修复Input支付宝小程序number/digit类型使用maxlength=-1时v-model失效的问题 ([7aa21b0](https://github.com/Moonofweisheng/wot-design-uni/commit/7aa21b0baadeccf4f0eb179f74332013acec6a10))
# 更新日志
### [1.2.24](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.23...v1.2.24) (2024-06-03)
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复Input支付宝小程序number/digit类型使用maxlength=-1时v-model失效的问题 ([7aa21b0](https://github.com/Moonofweisheng/wot-design-uni/commit/7aa21b0baadeccf4f0eb179f74332013acec6a10))
### [1.2.23](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.22...v1.2.23) (2024-06-02)
### ✏️ Documentation | 文档
* ✏️ 更新LICENSE文件地址 ([dae3ffc](https://github.com/Moonofweisheng/wot-design-uni/commit/dae3ffcc7b488dd6d87bc1c5e8ae16a78b794f85))
* ✏️ 修复loading组件示例代码中文标点符号、img-cropper组件示例代码标签缺失的问题 ([#347](https://github.com/Moonofweisheng/wot-design-uni/issues/347)) ([d171255](https://github.com/Moonofweisheng/wot-design-uni/commit/d171255899d232f141c84aa1251c03cc1d0a0b75))
* update select-picker doc ([#346](https://github.com/Moonofweisheng/wot-design-uni/issues/346)) ([7454452](https://github.com/Moonofweisheng/wot-design-uni/commit/7454452ad44331f329408cead9b483cf774cce5f))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复Cell的value为0时无法渲染的问题 ([dc64c09](https://github.com/Moonofweisheng/wot-design-uni/commit/dc64c09e6c6f991fe6f8f9fcfa309392e233ce21))
* 🐛 修复Sticky在h5和App端缓慢拖动时存在几率始终固定在顶部的问题 ([#350](https://github.com/Moonofweisheng/wot-design-uni/issues/350)) ([c5b3c5f](https://github.com/Moonofweisheng/wot-design-uni/commit/c5b3c5f68e1bb376249ed5f2c30b1898cc375abe))
### ✨ Features | 新功能
* ✨ 调整Circle环形进度条在微信小程序端使用canvas2d支持同层渲染 ([#351](https://github.com/Moonofweisheng/wot-design-uni/issues/351)) ([4489517](https://github.com/Moonofweisheng/wot-design-uni/commit/44895179e4688ceb995ea1968d23df4f0bf9cdc2))
### [1.2.22](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.21...v1.2.22) (2024-05-23)
### ✏️ Documentation | 文档
* ✏️ 组件库介绍组件数量调整至70+ ([efd55ca](https://github.com/Moonofweisheng/wot-design-uni/commit/efd55ca8afc07368b8d9f348d73c9a25cf186c47))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复Form指定prop为`a.b`时校验失败的问题 ([#329](https://github.com/Moonofweisheng/wot-design-uni/issues/329)) ([ab600b9](https://github.com/Moonofweisheng/wot-design-uni/commit/ab600b915a647ff089d5cfbb0ac955e3baa581c3))
### [1.2.21](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.20...v1.2.21) (2024-05-20)
### ✨ Features | 新功能
* ✨ 添加索引栏组件 ([#321](https://github.com/Moonofweisheng/wot-design-uni/issues/321)) ([f84e9af](https://github.com/Moonofweisheng/wot-design-uni/commit/f84e9affb1a044a37661c5d1dc118d834b49239c))
* ✨ img组件添加loading、error插槽 ([#323](https://github.com/Moonofweisheng/wot-design-uni/issues/323)) ([00ffa9f](https://github.com/Moonofweisheng/wot-design-uni/commit/00ffa9f3e54f3ba9eec967887e195c0266ef0a41))
* ✨ skeleton添加默认内容插槽 ([#322](https://github.com/Moonofweisheng/wot-design-uni/issues/322)) ([9a68c47](https://github.com/Moonofweisheng/wot-design-uni/commit/9a68c477dbf5e0f30f74882df92251eac707fdde))
* add backtop ([#314](https://github.com/Moonofweisheng/wot-design-uni/issues/314)) ([bf9e55a](https://github.com/Moonofweisheng/wot-design-uni/commit/bf9e55a24e676a764b1e035ca86bd6fe26b87420))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复Cell组件单独使用时设置border无效的问题 ([19b9f19](https://github.com/Moonofweisheng/wot-design-uni/commit/19b9f196466b88456e8b3e7221afd710da3df99b))
* 🐛 修复Picker选择器多列选择模式绑定值为空数组时将列第一项作为显示值的问题 ([c3b96ce](https://github.com/Moonofweisheng/wot-design-uni/commit/c3b96ce912bfc13d30c09393dd57cbcbf2d0b80a))
* 🐛 修复Sticky吸顶组件在微信小程序中放置在页面顶部时吸顶失效的问题 ([4ca3ebe](https://github.com/Moonofweisheng/wot-design-uni/commit/4ca3ebe7202f118a1bf6a462b27dc76ab6c720f9)), closes [#325](https://github.com/Moonofweisheng/wot-design-uni/issues/325)
* 修复wd-button在自定义样式时激活态样式问题 ([#312](https://github.com/Moonofweisheng/wot-design-uni/issues/312)) ([7544d69](https://github.com/Moonofweisheng/wot-design-uni/commit/7544d690f176b44a8e016688723af70d2a77388a))
### ✏️ Documentation | 文档
* ✏️ 常见问题增加关于useToast等hooks的答疑以及自定义编译平台的内容 ([65597c7](https://github.com/Moonofweisheng/wot-design-uni/commit/65597c76b812e5e61be17879de320989d0873df4))
* ✏️ 文档中增加解释导入方式的faq ([83fa0b0](https://github.com/Moonofweisheng/wot-design-uni/commit/83fa0b06927fddabd1021ee02c3c7f8377704786))
### [1.2.20](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.19...v1.2.20) (2024-05-12)
### ✏️ Documentation | 文档
* ✏️ 调整捐赠榜单和友情链接的数据到cloudflare上 ([1314373](https://github.com/Moonofweisheng/wot-design-uni/commit/1314373af1dff95aee4cd3cddefebcb3a6a5c5d2))
* ✏️ 推荐文档地址调整至cloudflare ([9119f30](https://github.com/Moonofweisheng/wot-design-uni/commit/9119f30b23676ad1b9a3869e362a3840ba288dc3))
* ✏️ Curtain组件width属性标记为number类型 ([d172ce7](https://github.com/Moonofweisheng/wot-design-uni/commit/d172ce7ffcfebf29b184b57a7f74a25acad1f967)), closes [#303](https://github.com/Moonofweisheng/wot-design-uni/issues/303)
### ✨ Features | 新功能
* Segmented组件添加click事件 ([#301](https://github.com/Moonofweisheng/wot-design-uni/issues/301)) ([225ce22](https://github.com/Moonofweisheng/wot-design-uni/commit/225ce225ac7faedffd4686b908076c47ba111695))
### 🐛 Bug Fixes | Bug 修复
* 🐛 修复MessageBox中使用TextArea字数统计样式错误的问题 ([b186ac0](https://github.com/Moonofweisheng/wot-design-uni/commit/b186ac09294a4fede16c514cd96ff94f661fcbc9)), closes [#290](https://github.com/Moonofweisheng/wot-design-uni/issues/290)
* 🐛 修复PickerView可以滚动到禁用选项的问题 ([edd44ed](https://github.com/Moonofweisheng/wot-design-uni/commit/edd44eda3fc9879dc980b02d1885d77530a3d2e8)), closes [#302](https://github.com/Moonofweisheng/wot-design-uni/issues/302)
* 🐛 修复Popover指定placement后箭头显示异常的问题([#306](https://github.com/Moonofweisheng/wot-design-uni/issues/306)) ([a9b108d](https://github.com/Moonofweisheng/wot-design-uni/commit/a9b108d231a8e537aab4ba49781590bcafb9354d))
* 🐛 修复release脚本处理最低版本号问题 ([c8077c9](https://github.com/Moonofweisheng/wot-design-uni/commit/c8077c9f3790e7844c902528d43596c4bc4025af))
* 🐛 修复Sticky组件获取节点错误的问题 ([5483ea6](https://github.com/Moonofweisheng/wot-design-uni/commit/5483ea6c447f85229af66b950e34c1dc690fadb1))
* 修复wd-calendar未抛出事件 ([c1203c9](https://github.com/Moonofweisheng/wot-design-uni/commit/c1203c91841c3d5bcd407923a577711e462207a3))
### [1.2.19](https://github.com/Moonofweisheng/wot-design-uni/compare/v1.2.18...v1.2.19) (2024-05-01)

View File

@@ -286,6 +286,7 @@
height: $size;
background-color: $bg;
position: absolute;
left: 0;
bottom: calc(-1 * $size / 2);
transform: rotateZ(45deg);
box-shadow: $box-shadow;
@@ -293,12 +294,14 @@
}
@include e(arrow-up) {
transform: translateX(-50%);
top: 0;
&:after {
content: "";
width: $size;
height: $size;
background-color: $bg;
position: absolute;
left: 0;
top: calc(-1 * $size / 2);
transform: rotateZ(45deg);
box-shadow: $box-shadow;
@@ -306,6 +309,7 @@
}
@include e(arrow-left) {
transform: translateY(-50%);
left: 0;
&:after {
content: "";
width: $size;
@@ -313,12 +317,15 @@
background-color: $bg;
position: absolute;
left: calc(-1 * $size / 2);
top: 0;
transform: rotateZ(45deg);
box-shadow: $box-shadow;
}
}
@include e(arrow-right) {
transform: translateY(-50%);
right: 0;
&:after {
content: "";
width: $size;
@@ -326,6 +333,7 @@
background-color: $bg;
position: absolute;
right: calc(-1 * $size / 2);
top: 0;
transform: rotateZ(45deg);
box-shadow: $box-shadow;
}

View File

@@ -869,3 +869,9 @@ $-password-input-cursor-duration: var(--wd-password-input-cursor-duration, 1s);
$-form-item-error-message-color: var(--wot-form-item-error-message-color, $-color-danger) !default;
$-form-item-error-message-font-size: var(--wot-form-item-error-message-font-size, $-fs-secondary) !default;
$-form-item-error-message-line-height: var(--wot-form-item-error-message-line-height, 24px) !default;
/* backtop */
$-backtop-bg: var(--wot-backtop-bg, #e1e1e1) !default;
/* index-bar */
$-index-bar-index-font-size: var(--wot-index-bar-index-font-size, $-fs-aid) !default;

View File

@@ -0,0 +1,49 @@
/**
* 适配 canvas 2d 上下文
* @param ctx canvas 2d 上下文
* @returns
*/
export function canvas2dAdapter(ctx: CanvasRenderingContext2D): UniApp.CanvasContext {
return Object.assign(ctx, {
setFillStyle(color: string | CanvasGradient) {
ctx.fillStyle = color
},
setStrokeStyle(color: string | CanvasGradient | CanvasPattern) {
ctx.strokeStyle = color
},
setLineWidth(lineWidth: number) {
ctx.lineWidth = lineWidth
},
setLineCap(lineCap: 'butt' | 'round' | 'square') {
ctx.lineCap = lineCap
},
setFontSize(font: string) {
ctx.font = font
},
setGlobalAlpha(alpha: number) {
ctx.globalAlpha = alpha
},
setLineJoin(lineJoin: 'bevel' | 'round' | 'miter') {
ctx.lineJoin = lineJoin
},
setTextAlign(align: 'left' | 'center' | 'right') {
ctx.textAlign = align
},
setMiterLimit(miterLimit: number) {
ctx.miterLimit = miterLimit
},
setShadow(offsetX: number, offsetY: number, blur: number, color: string) {
ctx.shadowOffsetX = offsetX
ctx.shadowOffsetY = offsetY
ctx.shadowBlur = blur
ctx.shadowColor = color
},
setTextBaseline(textBaseline: 'top' | 'bottom' | 'middle') {
ctx.textBaseline = textBaseline
},
createCircularGradient() {},
draw() {},
addColorStop() {}
}) as unknown as UniApp.CanvasContext
}

View File

@@ -0,0 +1,21 @@
@import '../common/abstracts/variable';
@import '../common/abstracts/mixin';
@include b(backtop) {
position: fixed;
background-color: $-backtop-bg;
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
color: $-color-gray-8;
@include when(circle) {
border-radius: 50%;
}
@include when(square) {
border-radius: 4px;
}
}

View File

@@ -0,0 +1,37 @@
import { baseProps, makeNumberProp, makeRequiredProp, makeStringProp } from '../common/props'
export const backtopProps = {
...baseProps,
/**
* 页面滚动距离
*/
scrollTop: makeRequiredProp(Number),
/**
* 距离顶部多少距离时显示
*/
top: makeNumberProp(300),
/**
* 返回顶部滚动时间
*/
duration: makeNumberProp(100),
/**
* 层级
*/
zIndex: makeNumberProp(10),
/**
* icon样式
*/
iconStyle: makeStringProp(''),
/**
* 形状
*/
shape: makeStringProp('circle'),
/**
* 距离屏幕底部距离
*/
bottom: makeNumberProp(100),
/**
* 距离屏幕右边距离
*/
right: makeNumberProp(20)
}

View File

@@ -0,0 +1,43 @@
<template>
<wd-transition :show="show" name="fade">
<view
:class="`wd-backtop ${customClass} is-${shape}`"
:style="`z-index: ${zIndex}; bottom: ${bottom}px; right: ${right}px; ${customStyle}`"
@click="handleBacktop"
>
<slot v-if="$slots.default"></slot>
<wd-icon v-else name="backtop" size="20px" :custom-style="iconStyle" />
</view>
</wd-transition>
</template>
<script lang="ts">
export default {
name: 'wd-backtop',
options: {
addGlobalClass: true,
virtualHost: true,
styleIsolation: 'shared'
}
}
</script>
<script lang="ts" setup>
import { computed } from 'vue'
import { backtopProps } from './types'
const props = defineProps(backtopProps)
const show = computed(() => props.scrollTop > props.top)
function handleBacktop() {
uni.pageScrollTo({
scrollTop: 0,
duration: props.duration
})
}
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>

View File

@@ -52,7 +52,7 @@
box-sizing: border-box;
border: none;
color: $-button-normal-color;
transition: all 0.2s;
transition: opacity 0.2s;
user-select: none;
font-weight: normal;
@@ -224,14 +224,7 @@
@include when(round) {
border-radius: 999px;
&::after {
border-radius: 999px;
}
&::before {
border-radius: 999px;
}
overflow: hidden;
}
@include when(text) {

View File

@@ -200,3 +200,10 @@ export type CalendarOnShortcutsClickOption = {
}
export type CalendarOnShortcutsClick = (option: CalendarOnShortcutsClickOption) => number | number[]
export type CalendarExpose = {
/** 关闭时间选择器弹窗 */
close: () => void
/** 打开时间选择器弹窗 */
open: () => void
}

View File

@@ -123,7 +123,7 @@ 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 { calendarProps } from './types'
import { calendarProps, type CalendarExpose } from './types'
import type { CalendarType } from '../wd-calendar-view/types'
const { translate } = useTranslate('calendar')
@@ -409,6 +409,11 @@ function handleShortcutClick(index: number) {
handleConfirm()
}
}
defineExpose<CalendarExpose>({
close,
open
})
</script>
<style lang="scss" scoped>

View File

@@ -1,5 +1,5 @@
import type { ExtractPropTypes } from 'vue'
import { baseProps, makeArrayProp, makeBooleanProp, makeStringProp } from '../common/props'
import { baseProps, makeArrayProp, makeBooleanProp, makeStringProp, makeNumericProp } from '../common/props'
import { type FormItemRule } from '../wd-form/types'
@@ -12,7 +12,7 @@ export const cellProps = {
/**
* 右侧内容
*/
value: String,
value: makeNumericProp(''),
/**
* 图标类名
*/

View File

@@ -32,8 +32,7 @@
<view class="wd-cell__body">
<!--文案内容-->
<view :class="`wd-cell__value ${customValueClass}`">
<template v-if="value">{{ value }}</template>
<slot v-else></slot>
<slot>{{ value }}</slot>
</view>
<!--箭头-->
<wd-icon v-if="isLink" custom-class="wd-cell__arrow-right" name="arrow-right" />
@@ -63,6 +62,7 @@ import { useCell } from '../composables/useCell'
import { useParent } from '../composables/useParent'
import { FORM_KEY } from '../wd-form/types'
import { cellProps } from './types'
import { isDef } from '../common/util'
const props = defineProps(cellProps)
const emit = defineEmits(['click'])
@@ -70,7 +70,7 @@ const emit = defineEmits(['click'])
const cell = useCell()
const isBorder = computed(() => {
return cell.border.value
return isDef(cell.border.value) ? cell.border.value : props.border
})
const { parent: form } = useParent(FORM_KEY)

View File

@@ -1,21 +1,20 @@
<template>
<view :class="`wd-circle ${customClass}`" :style="customStyle">
<canvas :width="canvasSize" :height="canvasSize" :style="style" :id="canvasId" :canvas-id="canvasId"></canvas>
<!-- #ifdef MP-WEIXIN -->
<canvas :style="canvasStyle" :id="canvasId" :canvas-id="canvasId" type="2d"></canvas>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<canvas :width="canvasSize" :height="canvasSize" :style="canvasStyle" :id="canvasId" :canvas-id="canvasId"></canvas>
<!-- #endif -->
<view v-if="!text" class="wd-circle__text">
<!-- 自定义提示内容 -->
<slot></slot>
</view>
<!-- #ifdef MP-WEIXIN -->
<cover-view v-else class="wd-circle__text">
{{ text }}
</cover-view>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<!-- eslint-disable-next-line vue/valid-v-else -->
<text v-else class="wd-circle__text">
{{ text }}
</text>
<!-- #endif -->
</view>
</template>
<script lang="ts">
@@ -29,10 +28,10 @@ export default {
}
</script>
<script lang="ts" setup>
// Circle 环形进度条
import { computed, getCurrentInstance, onBeforeMount, onMounted, onUnmounted, ref, watch } from 'vue'
import { addUnit, isObj, objToStyle, uuid } from '../common/util'
import { circleProps } from './types'
import { canvas2dAdapter } from '../common/canvasHelper'
// 大于等于0且小于等于100
function format(rate: number) {
@@ -47,23 +46,39 @@ const STEP = 1
const props = defineProps(circleProps)
const progressColor = ref<string | CanvasGradient>('') // 进度条颜色
const pixel = ref<number>(1) // 设备像素比
const currentValue = ref<number>(0) // 当前值
const interval = ref<any>(null) // 定时器
const canvasId = ref<string>(uuid()) // canvasId
const pixelRatio = ref<number>(1) // 像素比
const canvasId = ref<string>(`wd-circle${uuid()}`) // canvasId
let ctx: UniApp.CanvasContext | null = null
// canvas渲染大小
const canvasSize = computed(() => {
return props.size * pixel.value
let size = props.size
// #ifdef MP-ALIPAY
size = size * pixelRatio.value
// #endif
return size
})
// 进度条宽度
const sWidth = computed(() => {
let sWidth = props.strokeWidth
// #ifdef MP-ALIPAY
sWidth = sWidth * pixelRatio.value
// #endif
return sWidth
})
// Circle 样式
const style = computed(() => {
const canvasStyle = computed(() => {
const style = {
width: addUnit(props.size),
height: addUnit(props.size)
}
return `${objToStyle(style)}; ${props.customStyle}`
return `${objToStyle(style)};`
})
// 监听目标数值变化
@@ -96,38 +111,9 @@ watch(
{ immediate: false, deep: true }
)
// 监听轨道颜色变化
watch(
() => props.layerColor,
() => {
drawCircle(currentValue.value)
},
{ immediate: false }
)
// 监听轨道宽度
watch(
() => props.strokeWidth,
() => {
drawCircle(currentValue.value)
},
{ immediate: false }
)
// 监听轨道展示方向
watch(
() => props.clockwise,
() => {
drawCircle(currentValue.value)
},
{ immediate: false }
)
// #ifdef MP-ALIPAY
onBeforeMount(() => {
pixel.value = uni.getSystemInfoSync().pixelRatio
pixelRatio.value = uni.getSystemInfoSync().pixelRatio
})
// #endif
onMounted(() => {
currentValue.value = props.modelValue
@@ -143,32 +129,54 @@ const { proxy } = getCurrentInstance() as any
* 获取canvas上下文
*/
function getContext() {
if (!ctx) {
return new Promise<UniApp.CanvasContext>((resolve) => {
if (ctx) {
return resolve(ctx)
}
// #ifndef MP-WEIXIN
ctx = uni.createCanvasContext(canvasId.value, proxy)
}
return Promise.resolve(ctx)
resolve(ctx)
// #endif
// #ifdef MP-WEIXIN
uni
.createSelectorQuery()
.in(proxy)
.select(`#${canvasId.value}`)
.node((res) => {
if (res && res.node) {
const canvas = res.node
ctx = canvas2dAdapter(canvas.getContext('2d') as CanvasRenderingContext2D)
canvas.width = props.size * pixelRatio.value
canvas.height = props.size * pixelRatio.value
ctx.scale(pixelRatio.value, pixelRatio.value)
resolve(ctx)
}
})
.exec()
// #endif
})
}
/**
* 设置canvas
*/
function presetCanvas(context: any, strokeStyle: string | CanvasGradient, beginAngle: number, endAngle: number, fill?: string) {
const canvasSize = props.size * pixel.value
let strokeWidth = props.strokeWidth * pixel.value
const position = canvasSize / 2
let width = sWidth.value
const position = canvasSize.value / 2
if (!fill) {
strokeWidth = strokeWidth / 2
width = width / 2
}
const radius = position - strokeWidth / 2
const radius = position - width / 2
context.strokeStyle = strokeStyle
context.setLineWidth(strokeWidth)
context.setStrokeStyle(strokeStyle)
context.setLineWidth(width)
context.setLineCap(props.strokeLinecap)
context.beginPath()
context.arc(position, position, radius, beginAngle, endAngle, !props.clockwise)
context.stroke()
if (fill) {
context.setLineWidth(strokeWidth)
context.setLineWidth(width)
context.setFillStyle(fill)
context.fill()
}
@@ -184,14 +192,13 @@ function renderLayerCircle(context: UniApp.CanvasContext) {
* 渲染进度条
*/
function renderHoverCircle(context: UniApp.CanvasContext, formatValue: number) {
const canvasSize = props.size * pixel.value
// 结束角度
const progress = PERIMETER * (formatValue / 100)
const endAngle = props.clockwise ? BEGIN_ANGLE + progress : 3 * Math.PI - (BEGIN_ANGLE + progress)
// 设置进度条颜色
if (isObj(props.color)) {
const LinearColor = context.createLinearGradient(canvasSize, 0, 0, 0)
const LinearColor = context.createLinearGradient(canvasSize.value, 0, 0, 0)
Object.keys(props.color)
.sort((a, b) => parseFloat(a) - parseFloat(b))
.map((key) => LinearColor.addColorStop(parseFloat(key) / 100, (props.color as Record<string, any>)[key]))
@@ -207,12 +214,11 @@ function renderHoverCircle(context: UniApp.CanvasContext, formatValue: number) {
* 进度值为0时渲染一个圆点
*/
function renderDot(context: UniApp.CanvasContext) {
const canvasSize = props.size * pixel.value
const strokeWidth = props.strokeWidth * pixel.value // 管道宽度=小圆点直径
const position = canvasSize / 2 // 坐标
const strokeWidth = sWidth.value // 管道宽度=小圆点直径
const position = canvasSize.value / 2 // 坐标
// 设置进度条颜色
if (isObj(props.color)) {
const LinearColor = context.createLinearGradient(canvasSize, 0, 0, 0)
const LinearColor = context.createLinearGradient(canvasSize.value, 0, 0, 0)
Object.keys(props.color)
.sort((a, b) => parseFloat(a) - parseFloat(b))
.map((key) => LinearColor.addColorStop(parseFloat(key) / 100, (props.color as Record<string, any>)[key]))
@@ -230,9 +236,8 @@ function renderDot(context: UniApp.CanvasContext) {
* 画圆
*/
function drawCircle(currentValue: number) {
const canvasSize = props.size * pixel.value
getContext().then((context) => {
context.clearRect(0, 0, canvasSize, canvasSize)
context.clearRect(0, 0, canvasSize.value, canvasSize.value)
renderLayerCircle(context)
const formatValue = format(currentValue)

View File

@@ -61,7 +61,7 @@ async function validate(prop?: string): Promise<{ valid: boolean; errors: ErrorM
valid = false
break
}
if (rule.pattern && !rule.pattern.test(props.model[prop])) {
if (rule.pattern && !rule.pattern.test(value)) {
errors.push({
prop,
message: rule.message
@@ -71,7 +71,7 @@ async function validate(prop?: string): Promise<{ valid: boolean; errors: ErrorM
}
const { validator, ...ruleWithoutValidator } = rule
if (validator) {
const result = validator(props.model[prop], ruleWithoutValidator)
const result = validator(value, ruleWithoutValidator)
if (isPromise(result)) {
promises.push(
result

View File

@@ -1,6 +1,16 @@
<template>
<view :class="rootClass" @click="handleClick" :style="rootStyle">
<image :class="`wd-img__image ${customImage}`" :src="src" :mode="mode" :lazy-load="lazyLoad" @load="handleLoad" @error="handleError" />
<image
:class="`wd-img__image ${customImage}`"
:style="status !== 'success' ? 'width: 0;height: 0;' : ''"
:src="src"
:mode="mode"
:lazy-load="lazyLoad"
@load="handleLoad"
@error="handleError"
/>
<slot v-if="status === 'loading'" name="loading"></slot>
<slot v-if="status === 'error'" name="error"></slot>
</view>
</template>
<script lang="ts">
@@ -15,7 +25,7 @@ export default {
</script>
<script lang="ts" setup>
import { computed } from 'vue'
import { computed, ref } from 'vue'
import { addUnit, isDef, objToStyle } from '../common/util'
import { imgProps } from './types'
@@ -41,7 +51,10 @@ const rootClass = computed(() => {
return `wd-img ${props.round ? 'is-round' : ''} ${props.customClass}`
})
const status = ref<'loading' | 'error' | 'success'>('loading')
function handleError(event: Event) {
status.value = 'error'
emit('error', event)
}
function handleClick() {
@@ -53,6 +66,7 @@ function handleClick() {
emit('click')
}
function handleLoad(event: Event) {
status.value = 'success'
emit('load', event)
}
</script>

View File

@@ -0,0 +1,35 @@
@import "./../common/abstracts/_mixin.scss";
@import "./../common/abstracts/variable.scss";
.wot-theme-dark {
@include b(index-anchor) {
background-color: $-color-gray-8;
color: $-color-white;
}
}
// #ifdef MP-DINGTALK
@include b(index-anchor-ding) {
@include when(sticky){
position: sticky;
top: 0;
left: 0;
z-index: 1;
}
}
// #endif
@include b(index-anchor) {
background-color: $-color-gray-2;
padding: 10px;
font-size: 14px;
color: $-color-title;
@include when(sticky){
position: sticky;
top: 0;
left: 0;
z-index: 1;
}
}

View File

@@ -0,0 +1,9 @@
import type { ExtractPropTypes } from 'vue'
import { baseProps, makeRequiredProp } from '../common/props'
export const indexAnchorProps = {
...baseProps,
index: makeRequiredProp([String, Number])
}
export type IndexAnchorProps = ExtractPropTypes<typeof indexAnchorProps>

View File

@@ -0,0 +1,53 @@
<template>
<!-- #ifdef MP-DINGTALK -->
<view :class="`wd-index-anchor-ding ${isSticky ? 'is-sticky' : ''}`">
<!-- #endif -->
<view :class="`wd-index-anchor ${isSticky ? 'is-sticky' : ''} ${customClass}`" :style="customStyle" :id="indexAnchorId">
<slot>
{{ index }}
</slot>
</view>
<!-- #ifdef MP-DINGTALK -->
</view>
<!-- #endif -->
</template>
<script setup lang="ts">
import { indexAnchorProps } from './type'
import { onMounted, getCurrentInstance, ref, computed } from 'vue'
import { indexBarInjectionKey } from '../wd-index-bar/type'
import { getRect, isDef, uuid } from '../common/util'
import { useParent } from '../composables/useParent'
const props = defineProps(indexAnchorProps)
const { parent: indexBar } = useParent(indexBarInjectionKey)
const indexAnchorId = ref<string>(`indexBar${uuid()}`)
const { proxy } = getCurrentInstance()!
const isSticky = computed(() => {
return indexBar && indexBar.props.sticky && indexBar.anchorState.activeIndex === props.index
})
function getInfo() {
getRect(`#${indexAnchorId.value}`, false, proxy).then((res) => {
if (isDef(indexBar)) {
const anchor = indexBar.anchorState.anchorList.find((v) => v.index === props.index)!
anchor.top = res.top!
}
})
}
onMounted(() => {
if (isDef(indexBar)) {
indexBar.anchorState.anchorList.push({ top: 0, index: props.index })
}
getInfo()
})
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>

View File

@@ -0,0 +1,39 @@
@import "./../common/abstracts/_mixin.scss";
@import "./../common/abstracts/variable.scss";
.wot-theme-dark {
@include b(index-bar) {
@include e(index) {
color: $-color-white;
}
}
}
@include b(index-bar) {
position: relative;
width: 100%;
height: 100%;
@include e(content) {
width: 100%;
height: 100%;
}
@include e(sidebar) {
position: absolute;
top: 50%;
right: 4px;
transform: translateY(-50%);
}
@include e(index) {
font-size: 12px;
font-weight: $-fw-medium;
color: $-color-title;
padding: 4px 6px;
@include when(active) {
color: $-color-theme;
}
}
}

View File

@@ -0,0 +1,30 @@
import type { Ref } from 'vue'
import type { InjectionKey } from 'vue'
import type { ExtractPropTypes } from 'vue'
import { makeBooleanProp } from '../common/props'
export type AnchorIndex = number | string
export interface AnchorItem {
top: number
index: AnchorIndex
}
export const indexBarProps = {
/**
* @description 索引是否吸顶
*/
sticky: makeBooleanProp(false)
}
export type IndexBarProps = ExtractPropTypes<typeof indexBarProps>
export type InderBarProvide = {
props: { sticky?: boolean }
anchorState: {
anchorList: AnchorItem[] // 锚点列表
activeIndex: AnchorIndex | null // 当前激活的索引
}
}
export const indexBarInjectionKey: InjectionKey<InderBarProvide> = Symbol('wd-index-bar')

View File

@@ -0,0 +1,118 @@
<template>
<view class="wd-index-bar" :id="indexBarId">
<!-- #ifdef MP-DINGTALK -->
<view class="wd-index-bar" :id="indexBarId">
<!-- #endif -->
<scroll-view :scrollTop="scrollTop" :scroll-y="true" class="wd-index-bar__content" @scroll="hanleScroll">
<slot></slot>
</scroll-view>
<view
class="wd-index-bar__sidebar"
@touchmove.stop.prevent="handleTouchMove"
@touchend.stop.prevent="handleTouchEnd"
@touchcancel.stop.prevent="handleTouchEnd"
>
<view
class="wd-index-bar__index"
:class="{ 'is-active': item.index === state.activeIndex }"
v-for="item in state.anchorList"
:key="item.index"
>
{{ item.index }}
</view>
</view>
<!-- #ifdef MP-DINGTALK -->
</view>
<!-- #endif -->
</view>
</template>
<script setup lang="ts">
import type { AnchorItem, AnchorIndex } from './type'
import { indexBarInjectionKey, indexBarProps } from './type'
import { ref, getCurrentInstance, onMounted, reactive } from 'vue'
import { getRect, isDef, uuid } from '../common/util'
import { useChildren } from '../composables/useChildren'
const props = defineProps(indexBarProps)
const indexBarId = ref<string>(`indexBar${uuid()}`)
const { proxy } = getCurrentInstance()!
const state = reactive({
activeIndex: null as AnchorIndex | null,
anchorList: [] as AnchorItem[]
})
const { linkChildren } = useChildren(indexBarInjectionKey)
linkChildren({ props, anchorState: state })
const scrollTop = ref(0)
// 组件距离页面顶部的高度
let offsetTop = 0
let sidebarInfo = {
// 侧边栏距离顶部的高度
offsetTop: 0,
// 高度固定24px
indexHeight: 24
}
function init() {
setTimeout(() => {
state.activeIndex = state.anchorList[0]?.index
Promise.all([
getRect(`#${indexBarId.value}`, false, proxy),
getRect('.wd-index-bar__sidebar', false, proxy),
getRect('.wd-index-bar__index', false, proxy)
]).then(([bar, sidebar, index]) => {
offsetTop = bar.top!
sidebarInfo.offsetTop = sidebar.top!
sidebarInfo.indexHeight = index.height!
})
}, 100)
}
onMounted(() => {
init()
})
function hanleScroll(scrollEvent: any) {
const { detail } = scrollEvent
const anchor = state.anchorList.find((item, index) => {
if (!isDef(state.anchorList[index + 1])) return true
if (item.top - offsetTop <= detail.scrollTop && state.anchorList[index + 1].top - offsetTop > detail.scrollTop) return true
return false
})!
state.activeIndex = anchor.index
}
function getAnchorByPageY(pageY: number) {
const y = pageY - sidebarInfo.offsetTop
let idx = Math.floor(y / sidebarInfo.indexHeight)
if (idx < 0) idx = 0
else if (idx > state.anchorList.length - 1) idx = state.anchorList.length - 1
return state.anchorList[idx]
}
function handleTouchMove(e: TouchEvent) {
const clientY = e.touches[0].pageY
if (state.activeIndex === getAnchorByPageY(clientY).index) {
return
}
state.activeIndex = getAnchorByPageY(clientY).index
scrollTop.value = getAnchorByPageY(clientY).top - offsetTop
}
function handleTouchEnd(e: TouchEvent) {
const clientY = e.changedTouches[0].pageY
scrollTop.value = getAnchorByPageY(clientY).top - offsetTop
}
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>

View File

@@ -61,7 +61,12 @@ export const inputProps = {
/**
* 原生属性,最大长度
*/
maxlength: makeNumberProp(-1),
maxlength: {
type: Number,
// #ifndef MP-ALIPAY
default: -1
// #endif
},
/**
* 原生属性,禁用
*/

View File

@@ -57,7 +57,7 @@
<text
:class="[
inputValue && String(inputValue).length > 0 ? 'wd-input__count-current' : '',
String(inputValue).length > maxlength ? 'is-error' : ''
String(inputValue).length > maxlength! ? 'is-error' : ''
]"
>
{{ String(inputValue).length }}

View File

@@ -1,7 +1,7 @@
/*
* @Author: weisheng
* @Date: 2024-03-15 20:40:34
* @LastEditTime: 2024-03-18 14:59:32
* @LastEditTime: 2024-05-27 18:49:28
* @LastEditors: weisheng
* @Description:
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-loading\types.ts
@@ -10,13 +10,12 @@
import type { ExtractPropTypes } from 'vue'
import { baseProps, makeNumericProp, makeStringProp } from '../common/props'
// 'circle-outline' | 'circle-ring' 废弃
export type LoadingType = 'outline' | 'ring' | 'circle-outline' | 'circle-ring' // 提示信息加载状态类型
export type LoadingType = 'outline' | 'ring' // 提示信息加载状态类型
export const loadingProps = {
...baseProps,
/**
* 加载指示器类型,可选值:'outline' | 'ring' | 'circle-outline' | 'circle-ring'
* 加载指示器类型,可选值:'outline' | 'ring'
*/
type: makeStringProp<LoadingType>('ring'),
/**

View File

@@ -1,10 +1,10 @@
<template>
<view :class="rootClass" :style="rootStyle">
<view v-if="!type || type === 'ring' || type === 'circle-ring'" class="wd-loading__body">
<view v-if="!type || type === 'ring'" class="wd-loading__body">
<view class="wd-loading__svg" :style="`background-image: url(${svg});`"></view>
</view>
<view v-if="type === 'circle-outline' || type === 'outline'" class="wd-loading__body">
<view v-if="type === 'outline'" class="wd-loading__body">
<view class="wd-loading__svg" :style="`background-image: url(${svg});`"></view>
</view>
</view>
@@ -23,7 +23,7 @@ export default {
<script lang="ts" setup>
import { computed, onBeforeMount, ref, watch } from 'vue'
import base64 from '../common/base64'
import { gradient, context, objToStyle, addUnit } from '../common/util'
import { gradient, context, objToStyle, addUnit, isDef } from '../common/util'
import { loadingProps } from './types'
const svgDefineId = context.id++
@@ -86,19 +86,8 @@ onBeforeMount(() => {
function buildSvg() {
const { type, color } = props
let adaptType: 'outline' | 'ring' = 'ring'
// 2.2.0 版本向下兼容 circle-outline 和 circle-ring;
if (type === 'circle-outline') {
adaptType = 'outline'
} else if (type === 'outline') {
adaptType = 'outline'
} else if (type === 'circle-ring') {
adaptType = 'ring'
}
const svgStr = `"data:image/svg+xml;base64,${base64(
adaptType === 'ring' ? icon[adaptType](color, intermediateColor.value) : icon[adaptType](color)
)}"`
let ringType: 'outline' | 'ring' = isDef(type) ? type : 'ring'
const svgStr = `"data:image/svg+xml;base64,${base64(ringType === 'ring' ? icon[ringType](color, intermediateColor.value) : icon[ringType](color))}"`
svg.value = svgStr
}
</script>

View File

@@ -60,7 +60,6 @@
font-size: $-message-box-content-fs;
text-align: center;
overflow: auto;
word-break: break-all;
line-height: 20px;
&::-webkit-scrollbar {

View File

@@ -11,29 +11,20 @@
:duration="200"
>
<view :class="rootClass">
<!--内容部分-->
<view :class="bodyClass">
<!--公共title-->
<view v-if="title" class="wd-message-box__title">
{{ title }}
</view>
<!--其它类型-->
<view class="wd-message-box__content">
<!--prompt类型-->
<block v-if="type === 'prompt'">
<!--输入框-->
<wd-input v-model="inputValue" :type="inputType" size="large" :placeholder="inputPlaceholder || '请输入'" @input="inputValChange" />
<!--错误提示-->
<view v-if="showErr" class="wd-message-box__input-error">
{{ inputError || translate('inputNoValidate') }}
</view>
</block>
<!--使用插槽-->
<slot>{{ msg }}</slot>
<!--使用文本-->
</view>
</view>
<!--action按钮组合-->
<view :class="`wd-message-box__actions ${showCancelButton ? 'wd-message-box__flex' : 'wd-message-box__block'}`">
<wd-button type="info" block v-if="showCancelButton" custom-style="margin-right: 16px;" @click="toggleModal('cancel')">
{{ cancelButtonText || translate('cancel') }}
@@ -183,15 +174,13 @@ watch(
)
/**
* @description 关闭消息框的统一主调 handle
* @param {'cancel' | 'confirm'} action
* 点击操作
* @param action
*/
function toggleModal(action: 'confirm' | 'cancel' | 'modal') {
// closeOnClickModal为false此时点击蒙层没任何效果
if (action === 'modal' && !closeOnClickModal.value) {
return
}
// prompt类型的弹窗 文案没有通过校验,点击了确定按钮没有任何效果
if (type.value === 'prompt' && action === 'confirm' && !validate()) {
return
}
@@ -228,6 +217,10 @@ function toggleModal(action: 'confirm' | 'cancel' | 'modal') {
}
}
/**
* 确认回调
* @param result
*/
function handleConfirm(result: MessageResult) {
show.value = false
if (isFunction(onConfirm)) {
@@ -235,6 +228,10 @@ function handleConfirm(result: MessageResult) {
}
}
/**
* 取消回调
* @param result
*/
function handleCancel(result: MessageResult) {
show.value = false
if (isFunction(onCancel)) {

View File

@@ -5,19 +5,22 @@
<view class="wd-navbar__capsule" v-if="$slots.capsule">
<slot name="capsule" />
</view>
<view
:class="`wd-navbar__left ${leftDisabled ? 'is-disabled' : ''}`"
:hover-class="leftDisabled ? '' : 'wd-navbar__left--hover'"
:hover-class="leftDisabled || $slots.left ? '' : 'wd-navbar__left--hover'"
hover-stay-time="70"
@click="handleClickLeft"
v-if="!$slots.capsule && ($slots.left || leftArrow || leftText)"
v-else-if="!$slots.left"
>
<slot name="left" />
<block v-if="!$slots.left && (leftArrow || leftText)">
<wd-icon v-if="leftArrow" size="24px" name="arrow-left" custom-class="wd-navbar__arrow" />
<view v-if="leftText" class="wd-navbar__text">{{ leftText }}</view>
</block>
<wd-icon v-if="leftArrow" size="24px" name="arrow-left" custom-class="wd-navbar__arrow" />
<view v-if="leftText" class="wd-navbar__text">{{ leftText }}</view>
</view>
<view v-else :class="`wd-navbar__left ${leftDisabled ? 'is-disabled' : ''}`" @click="handleClickLeft">
<slot name="left" />
</view>
<view class="wd-navbar__title">
<slot name="title" />
<block v-if="!$slots.title && title">{{ title }}</block>

View File

@@ -14,6 +14,7 @@
@include b(number-keyboard) {
width: 100%;
background: $-number-keyboard-background;
color: $-color-black;
user-select: none;
@include m(with-title) {

View File

@@ -174,6 +174,9 @@ function selectWithIndex(columnIndex: number, rowIndex: number) {
throw Error(`The value to select with Col:${columnIndex} Row:${rowIndex} is correct`)
}
const select: number[] = deepClone(selectedIndex.value)
select[columnIndex] = rowIndex
selectedIndex.value = deepClone(select)
// 被禁用的无法选中,选中距离它最近的未被禁用的
if (col[rowIndex].disabled) {
// 寻找值为0或最最近的未被禁用的节点的索引
@@ -189,10 +192,10 @@ function selectWithIndex(columnIndex: number, rowIndex: number) {
} else if (select[columnIndex] === undefined) {
select[columnIndex] = 0
}
} else {
select[columnIndex] = rowIndex
nextTick(() => {
selectedIndex.value = deepClone(select)
})
}
selectedIndex.value = deepClone(select)
return selectedIndex.value
}

View File

@@ -89,7 +89,7 @@ export default {
import { getCurrentInstance, onBeforeMount, ref, watch, computed, onMounted, nextTick } from 'vue'
import { deepClone, defaultDisplayFormat, getType, isArray, isDef, isFunction } from '../common/util'
import { useCell } from '../composables/useCell'
import { type ColumnItem, formatArray } 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'
@@ -99,7 +99,7 @@ const { translate } = useTranslate('picker')
const props = defineProps(pickerProps)
const emit = defineEmits(['confirm', 'open', 'cancel', 'update:modelValue'])
const pickerViewWd = ref<any>(null)
const pickerViewWd = ref<PickerViewInstance | null>(null)
const cell = useCell()
const innerLoading = ref<boolean>(false) // 内部控制是否loading
@@ -124,12 +124,8 @@ watch(
if (fn && !isFunction(fn)) {
console.error('The type of displayFormat must be Function')
}
if (pickerViewWd.value && pickerViewWd.value.selectedIndex && pickerViewWd.value.selectedIndex.length !== 0) {
if (isDef(props.modelValue) && props.modelValue !== '') {
setShowValue(pickerViewWd.value.getSelects())
} else {
showValue.value = ''
}
if (pickerViewWd.value && pickerViewWd.value.getSelectedIndex().length !== 0) {
handleShowValueUpdate(props.modelValue)
}
},
{
@@ -143,17 +139,7 @@ watch(
(newValue) => {
pickerValue.value = newValue
// 获取初始选中项,并展示初始选中文案
if (isDef(newValue) && newValue !== '') {
if (pickerViewWd.value && pickerViewWd.value.getSelects) {
nextTick(() => {
setShowValue(pickerViewWd.value!.getSelects())
})
} else {
setShowValue(getSelects(newValue)!)
}
} else {
showValue.value = ''
}
handleShowValueUpdate(newValue)
},
{
deep: true,
@@ -167,17 +153,7 @@ watch(
displayColumns.value = newValue
resetColumns.value = newValue
// 获取初始选中项,并展示初始选中文案
if (isDef(props.modelValue) && props.modelValue !== '') {
if (pickerViewWd.value && pickerViewWd.value.getSelects) {
nextTick(() => {
setShowValue(pickerViewWd.value!.getSelects())
})
} else {
setShowValue(getSelects(props.modelValue)!)
}
} else {
showValue.value = ''
}
handleShowValueUpdate(props.modelValue)
},
{
deep: true,
@@ -226,10 +202,7 @@ const isRequired = computed(() => {
const { proxy } = getCurrentInstance() as any
onMounted(() => {
isDef(props.modelValue) && props.modelValue !== '' && setShowValue(getSelects(props.modelValue)!)
if (isDef(props.modelValue) && props.modelValue !== '' && pickerViewWd.value && pickerViewWd.value.getSelects) {
setShowValue(pickerViewWd.value!.getSelects())
}
handleShowValueUpdate(props.modelValue)
})
onBeforeMount(() => {
@@ -237,6 +210,25 @@ onBeforeMount(() => {
resetColumns.value = deepClone(props.columns)
})
/**
* 值变更时更新显示内容
* @param value
*/
function handleShowValueUpdate(value: string | number | Array<string | number>) {
// 获取初始选中项,并展示初始选中文案
if ((isArray(value) && value.length > 0) || (isDef(value) && !isArray(value) && value !== '')) {
if (pickerViewWd.value) {
nextTick(() => {
setShowValue(pickerViewWd.value!.getSelects())
})
} else {
setShowValue(getSelects(value)!)
}
} else {
showValue.value = ''
}
}
/**
* @description 根据传入的valuepicker组件获取当前cell展示值。
* @param {String|Number|Array<String|Number|Array<any>>}value
@@ -344,6 +336,7 @@ function handleConfirm() {
popupShow.value = false
resetColumns.value = deepClone(columns)
emit('update:modelValue', values)
setShowValue(selects)
emit('confirm', {
value: values,

View File

@@ -88,6 +88,13 @@ watch(
}
)
watch(
() => props.placement,
() => {
popover.init(props.placement, props.visibleArrow, selector)
}
)
watch(
() => props.modelValue,
(newValue) => {

View File

@@ -38,7 +38,7 @@ import { segmentedProps, type SegmentedInfo, type SegmentedOption } from './type
const $item = '.wd-segmented__item'
const props = defineProps(segmentedProps)
const emit = defineEmits(['update:value', 'change'])
const emit = defineEmits(['update:value', 'change', 'click'])
const sectionItemInfo = reactive<SegmentedInfo>({
width: 0,
@@ -130,6 +130,7 @@ function handleClick(option: string | number | SegmentedOption, index: number) {
updateActiveStyle()
emit('update:value', value)
emit('change', isObj(option) ? option : { value })
emit('click', isObj(option) ? option : { value })
}
</script>

View File

@@ -1,4 +1,4 @@
import type { PropType, CSSProperties, ExtractPropTypes } from 'vue'
import type { PropType, ExtractPropTypes, CSSProperties } from 'vue'
import { makeArrayProp, makeBooleanProp, makeStringProp } from '../common/props'
type SkeletonTheme = 'text' | 'avatar' | 'paragraph' | 'image'
@@ -16,7 +16,7 @@ export type SkeletonRowColObj = {
borderRadius?: string | number
backgroundColor?: string
}
export type SkeletonRowCol = Array<number | SkeletonRowColObj | Array<SkeletonRowColObj>>
export type SkeletonRowCol = number | SkeletonRowColObj | Array<SkeletonRowColObj>
export type SkeletonThemeVars = {
notifyPadding?: string
notifyFontSize?: string

View File

@@ -9,11 +9,14 @@
-->
<template>
<view :class="`wd-skeleton ${customClass}`" :style="customStyle">
<view class="wd-skeleton__content" v-if="parsedRowCols.length">
<view class="wd-skeleton__content" v-if="show">
<view class="wd-skeleton__row" v-for="(row, index) of parsedRowCols" :key="`row-${index}`">
<view v-for="(col, idx) of row" :key="`col-${idx}`" :class="col.class" :style="col.style" />
</view>
</view>
<view v-else>
<slot />
</view>
</view>
</template>
<script lang="ts">
@@ -45,7 +48,7 @@ const themeMap = {
paragraph: [1, 1, 1, { width: '55%' }]
}
const props = defineProps(skeletonProps)
const rowCols = ref<SkeletonRowCol>([])
const rowCols = ref<SkeletonRowCol[]>([])
const parsedRowCols = computed(() => {
return rowCols.value.map((item) => {
@@ -107,6 +110,8 @@ watch(
},
{ immediate: true }
)
const show = computed(() => props.loading == undefined || props.loading === true)
</script>
<style lang="scss" scoped>

View File

@@ -57,10 +57,10 @@ function handleClick() {
}
}
}
emit('update:modelValue', value)
emit('change', {
value
})
emit('update:modelValue', value)
}
</script>
<style lang="scss" scoped>

View File

@@ -0,0 +1,20 @@
/*
* @Author: weisheng
* @Date: 2024-04-08 22:34:01
* @LastEditTime: 2024-06-01 16:04:56
* @LastEditors: weisheng
* @Description:
* @FilePath: /wot-design-uni/src/uni_modules/wot-design-uni/components/wd-sticky-box/types.ts
* 记得注释
*/
import type { ComponentInternalInstance, InjectionKey } from 'vue'
export type stickyBoxProvide = {
boxStyle: {
height: number // 高度
width: number // 宽度
}
observerForChild: (child: ComponentInternalInstance) => void // 监听子组件
}
export const STICKY_BOX_KEY: InjectionKey<stickyBoxProvide> = Symbol('wd-sticky-box')

View File

@@ -1,7 +1,7 @@
<template>
<view style="position: relative">
<view :class="`wd-sticky-box ${props.customClass}`" :style="customStyle" id="styckyBoxId">
<wd-resize @resize="resizeHandler">
<view :class="`wd-sticky-box ${props.customClass}`" :style="customStyle" :id="styckyBoxId">
<wd-resize @resize="handleResize">
<slot />
</wd-resize>
</view>
@@ -20,38 +20,43 @@ export default {
</script>
<script lang="ts" setup>
import { getCurrentInstance, onBeforeMount, provide, ref } from 'vue'
import { getCurrentInstance, onBeforeMount, reactive, ref } from 'vue'
import { getRect, uuid } from '../common/util'
import { baseProps } from '../common/props'
import { STICKY_BOX_KEY } from './types'
import { useChildren } from '../composables/useChildren'
const props = defineProps(baseProps)
const styckyBoxId = ref<string>(`wd-sticky-box${uuid()}`)
const observerMap = ref<Map<any, any>>(new Map())
const height = ref<number>(0)
const width = ref<number>(0)
const stickyList: any[] = [] // 子元素sticky列表
const boxStyle = reactive({
height: 0,
width: 0
})
const { proxy } = getCurrentInstance() as any
const instance = getCurrentInstance() as any
provide('box-height', height)
provide('box-width', width)
provide('observerForChild', observerForChild)
const { children: stickyList, linkChildren } = useChildren(STICKY_BOX_KEY)
linkChildren({
boxStyle: boxStyle,
observerForChild
})
onBeforeMount(() => {
observerMap.value = new Map()
})
/**
* @description wd-sticky-box 尺寸发生变化时重新监听所有的viewport
* 容器大小变化后重新监听sticky组件与box组件的交叉状态
* @param detail
*/
function resizeHandler(detail: any) {
function handleResize(detail: any) {
// 相对的容器大小改变后,同步设置 wd-sticky-box 的大小
width.value = detail.width
height.value = detail.height
boxStyle.width = detail.width
boxStyle.height = detail.height
// wd-sticky-box 大小变化时,重新监听所有吸顶元素
const temp = observerMap.value
observerMap.value = new Map()
@@ -67,8 +72,8 @@ function resizeHandler(detail: any) {
temp.clear()
}
/**
* @description 删除 wd-sticky 废弃的监听
* @param child
* 删除对指定sticky的监听
* @param child 指定的子组件
*/
function deleteObserver(child: any) {
const observer = observerMap.value.get(child.$.uid)
@@ -77,63 +82,70 @@ function deleteObserver(child: any) {
observerMap.value.delete(child.$.uid)
}
/**
* @description 为 wd-sticky 创建监听
* @param child
* 针对指定sticky添加监听
* @param child 指定的子组件
*/
function createObserver(child: any) {
const observer = uni.createIntersectionObserver(instance)
const observer = uni.createIntersectionObserver(proxy, { thresholds: [0, 0.5] })
observerMap.value.set(child.$.uid, observer)
return observer
}
/**
* @description 为单个 wd-sticky 监听 viewport
* @param child sticky
* 监听子组件
* @param child 子组件
*/
function observerForChild(child: any) {
const hasChild = stickyList.find((sticky) => {
return sticky.$.uid === child.$.uid
})
if (!hasChild) {
stickyList.push(child)
}
deleteObserver(child)
const observer = createObserver(child)
const exposed = child.$.exposed
const offset = exposed.height.value + exposed.offsetTop
let offset = exposed.stickyState.height + exposed.offsetTop
// #ifdef H5
// H5端导航栏为普通元素需要将组件移动到导航栏的下边沿
// H5的导航栏高度为44px
offset = offset + 44
// #endif
// 如果 wd-sticky 比 wd-sticky-box还大"相对吸顶"无任何意义,此时强制吸顶元素回归其占位符
if (height.value <= exposed.height.value) {
if (boxStyle.height <= exposed.stickyState.height) {
exposed.setPosition(false, 'absolute', 0)
}
observer.relativeToViewport({ top: -offset }).observe(`#${styckyBoxId.value}`, (result) => {
scrollHandler(exposed, result)
handleRelativeTo(exposed, result)
})
// 当子组件默认处于边界外且永远不会进入边界内时,需要手动调用一次
getRect(`#${styckyBoxId.value}`, false, proxy)
.then((res) => {
// 当 wd-sticky-box 位于 viewport 外部时不会触发 observe此时根据位置手动修复位置。
if (Number(res.bottom) <= offset) scrollHandler(exposed, { boundingClientRect: res })
// #ifdef H5
// H5端查询节点信息未计算导航栏高度
res.bottom = Number(res.bottom) + 44
// #endif
if (Number(res.bottom) <= offset) handleRelativeTo(exposed, { boundingClientRect: res })
})
.catch((res) => {
console.log(res)
})
}
/**
* @description 为子节点监听 viewport处理子节点的相对吸顶逻辑
* 监听容器组件
* @param {Object} exposed wd-sticky实例暴露出的事件
* @param {Object} boundingClientRect 目标节点各个边在viewport中的坐标
* @param {Object} boundingClientRect 边界信息
*/
function scrollHandler(exposed: any, { boundingClientRect }: any) {
const offset = exposed.height.value + exposed.offsetTop
if (boundingClientRect.bottom <= offset) {
// 父元素即将被吸顶元素遮盖,将吸顶元素固定到父元素底部
exposed.setPosition(true, 'absolute', boundingClientRect.height - exposed.height.value)
} else if (boundingClientRect.top <= offset && boundingClientRect.bottom > offset) {
// wd-sticky 已经完全呈现了 viewport 中了,
// 此时没有必要再相对 wd-sticky-box 吸顶了
if (exposed.state.value === 'normal') return
// 顶元素开始遮盖不住父元素了,将吸顶元素恢复到吸顶模式
exposed.setPosition(false, 'fixed', exposed.offsetTop)
function handleRelativeTo(exposed: any, { boundingClientRect }: any) {
let childOffsetTop = exposed.offsetTop
// #ifdef H5
// H5端导航栏为普通元素需要将组件移动到导航栏的下边沿
// H5的导航栏高度为44px
childOffsetTop = childOffsetTop + 44
// #endif
const offset = exposed.stickyState.height + childOffsetTop
let isAbsolute = boundingClientRect.bottom <= offset
// #ifdef H5 || APP-PLUS
isAbsolute = boundingClientRect.bottom < offset
// #endif
if (isAbsolute) {
exposed.setPosition(true, 'absolute', boundingClientRect.height - exposed.stickyState.height)
} else if (boundingClientRect.top <= offset && !isAbsolute) {
if (exposed.stickyState.state === 'normal') return
exposed.setPosition(false, 'fixed', childOffsetTop)
}
}
</script>

View File

@@ -1,13 +1,8 @@
<template>
<view :style="`${rootStyle};display: inline-block;`">
<!--强制设置高宽防止元素坍塌-->
<!--在使用 wd-sticky-box 某些情况下 wd-sticky__container 'positionabsolute' 需要相对于 wd-sticky-box-->
<view :class="`wd-sticky ${props.customClass}`" :style="stickyStyle" :id="styckyId">
<!--吸顶容器-->
<view :class="`wd-sticky ${customClass}`" :style="stickyStyle" :id="styckyId">
<view class="wd-sticky__container" :style="containerStyle">
<!--监听元素尺寸变化-->
<wd-resize @resize="resizeHandler" custom-style="display: inline-block;">
<!--需要吸顶的内容-->
<wd-resize @resize="handleResize" custom-style="display: inline-block;">
<slot />
</wd-resize>
</view>
@@ -20,63 +15,64 @@ export default {
name: 'wd-sticky',
options: {
addGlobalClass: true,
// virtualHost: true,
virtualHost: true,
styleIsolation: 'shared'
}
}
</script>
<script lang="ts" setup>
import { type Ref, computed, getCurrentInstance, inject, ref } from 'vue'
import { addUnit, getRect, objToStyle, uuid } from '../common/util'
import { computed, getCurrentInstance, reactive, ref, type CSSProperties } from 'vue'
import { addUnit, getRect, objToStyle, requestAnimationFrame, uuid } from '../common/util'
import { stickyProps } from './types'
import { useParent } from '../composables/useParent'
import { STICKY_BOX_KEY } from '../wd-sticky-box/types'
const props = defineProps(stickyProps)
const styckyId = ref<string>(`wd-sticky${uuid()}`)
const openBox = ref<boolean>(false)
const position = ref<string>('absolute')
const top = ref<number>(0)
const height = ref<number>(0)
const width = ref<number>(0)
const observerList = ref<UniApp.IntersectionObserver[]>([])
const state = ref<string>('')
const boxHeight: Ref<number> = inject('box-height', null) || ref(0)
// eslint-disable-next-line @typescript-eslint/ban-types
const observerForChild: Function | null = inject('observerForChild', null)
const stickyState = reactive({
position: 'absolute',
boxLeaved: false,
top: 0,
height: 0,
width: 0,
state: ''
})
const { parent: stickyBox } = useParent(STICKY_BOX_KEY)
const { proxy } = getCurrentInstance() as any
const instance = getCurrentInstance() as any
const rootStyle = computed(() => {
const style: Record<string, string | number> = {
const style: CSSProperties = {
'z-index': props.zIndex,
height: addUnit(height.value),
width: addUnit(width.value)
height: addUnit(stickyState.height),
width: addUnit(stickyState.width)
}
if (!openBox.value) {
if (!stickyState.boxLeaved) {
style['position'] = 'relative'
}
return `${objToStyle(style)};${props.customStyle}`
})
const stickyStyle = computed(() => {
const style: Record<string, string | number> = {
const style: CSSProperties = {
'z-index': props.zIndex,
height: addUnit(height.value),
width: addUnit(width.value)
height: addUnit(stickyState.height),
width: addUnit(stickyState.width)
}
if (!openBox.value) {
if (!stickyState.boxLeaved) {
style['position'] = 'relative'
}
return `${objToStyle(style)};`
})
const containerStyle = computed(() => {
const style: Record<string, string | number> = {
position: position.value,
top: addUnit(top.value)
const style: CSSProperties = {
position: stickyState.position as 'static' | 'relative' | 'absolute' | 'sticky' | 'fixed',
top: addUnit(stickyState.top)
}
return objToStyle(style)
})
@@ -93,7 +89,7 @@ const innerOffsetTop = computed(() => {
})
/**
* @description 清除无用的 viewport 观察者
* 清除对当前组件的监听
*/
function clearObserver() {
while (observerList.value.length !== 0) {
@@ -101,90 +97,92 @@ function clearObserver() {
}
}
/**
* @description 创建新的 viewport 观察者
* 添加对当前组件的监听
*/
function createObserver() {
const observer = uni.createIntersectionObserver(instance)
const observer = uni.createIntersectionObserver(proxy, { thresholds: [0, 0.5] })
observerList.value.push(observer)
return observer
}
/**
* @description 监听到吸顶元素尺寸大小变化时,立即重新模拟吸顶
* 当前内容高度发生变化时重置监听
*/
function resizeHandler(detail: any) {
// 当吸顶内容处于absolute、fixed时为了防止父容器坍塌需要手动设置父容器高宽。
width.value = detail.width
height.value = detail.height
// // 如果和 wd-sticky-box 配套使用,吸顶逻辑交由 wd-sticky-box 进行处理
observerContentScroll()
if (!observerForChild) return
observerForChild(proxy)
function handleResize(detail: any) {
stickyState.width = detail.width
stickyState.height = detail.height
requestAnimationFrame(() => {
observerContentScroll()
if (!stickyBox || !stickyBox.observerForChild) return
stickyBox.observerForChild(proxy)
})
}
/**
* @description 模拟吸顶逻辑
* 监听吸顶元素滚动事件
*/
function observerContentScroll() {
// 视图在 render tree 中未呈现,吸顶无任何意义。
if (height.value === 0 && width.value === 0) return
const offset = innerOffsetTop.value + height.value
if (stickyState.height === 0 && stickyState.width === 0) return
const offset = innerOffsetTop.value + stickyState.height
clearObserver()
createObserver()
.relativeToViewport({
top: -offset // viewport上边界往下拉
top: -offset
})
.observe(`#${styckyId.value}`, (result) => {
handleRelativeTo(result)
})
.observe(`#${styckyId.value}`, scrollHandler)
getRect(`#${styckyId.value}`, false, proxy).then((res) => {
// 当 wd-sticky 位于 viewport 外部时不会触发 observe此时根据位置手动修复位置。
if (Number(res.bottom) <= offset) scrollHandler({ boundingClientRect: res })
// #ifdef H5
// H5端查询节点信息未计算导航栏高度
res.bottom = Number(res.bottom) + 44
// #endif
if (Number(res.bottom) <= offset) handleRelativeTo({ boundingClientRect: res })
})
}
/**
* @description 根据位置进行吸顶
*/
function scrollHandler({ boundingClientRect }: any) {
function handleRelativeTo({ boundingClientRect }: any) {
// sticky 高度大于或等于 wd-sticky-box使用 wd-sticky-box 无任何意义
if (observerForChild && height.value >= boxHeight.value) {
position.value = 'absolute'
top.value = 0
if (stickyBox && stickyState.height >= stickyBox.boxStyle.height) {
stickyState.position = 'absolute'
stickyState.top = 0
return
}
// boundingClientRect : 目标节点各个边在 viewport 中的坐标
if (boundingClientRect.top <= innerOffsetTop.value) {
state.value = 'sticky'
// 开始吸顶,固定到顶部
openBox.value = false
position.value = 'fixed'
top.value = innerOffsetTop.value
} else if (boundingClientRect.top > innerOffsetTop.value) {
state.value = 'normal'
// 完全展示,结束吸顶
openBox.value = false
position.value = 'absolute'
top.value = 0
let isStycky = boundingClientRect.top <= innerOffsetTop.value
// #ifdef H5 || APP-PLUS
isStycky = boundingClientRect.top < innerOffsetTop.value
// #endif
if (isStycky) {
stickyState.state = 'sticky'
stickyState.boxLeaved = false
stickyState.position = 'fixed'
stickyState.top = innerOffsetTop.value
} else {
stickyState.state = 'normal'
stickyState.boxLeaved = false
stickyState.position = 'absolute'
stickyState.top = 0
}
}
/**
* 设置位置
* @param setOpenBox
* @param setboxLeaved
* @param setPosition
* @param setTop
*/
function setPosition(setOpenBox: boolean, setPosition: string, setTop: number) {
openBox.value = setOpenBox
position.value = setPosition
top.value = setTop
function setPosition(boxLeaved: boolean, position: string, top: number) {
stickyState.boxLeaved = boxLeaved
stickyState.position = position
stickyState.top = top
}
defineExpose({
setPosition,
openBox: openBox,
position: position,
top: top,
height: height,
width: width,
state: state,
offsetTop: innerOffsetTop.value
stickyState,
offsetTop: props.offsetTop
})
</script>
<style lang="scss" scoped>

View File

@@ -40,6 +40,7 @@
border-radius: 2px;
transition: opacity .3s;
vertical-align: middle;
line-height: initial;
@include when(default) {
@include tag-type-style($-tag-info-color, $-tag-info-bg);

View File

@@ -95,6 +95,10 @@ declare module '@vue/runtime-core' {
WdPasswordInput: typeof import('./components/wd-password-input/wd-password-input.vue')['default']
WdForm: typeof import('./components/wd-form/wd-form.vue')['default']
WdTextarea: typeof import('./components/wd-textarea/wd-textarea.vue')['default']
WdBacktop: typeof import('./components/wd-backtop/wd-backtop.vue')['default']
WdSkeleton: typeof import('./components/wd-skeleton/wd-skeleton.vue')['default']
WdIndexBar: typeof import('./components/wd-index-bar/wd-index-bar.vue')['default']
WdIndexAnchor: typeof import('./components/wd-index-anchor/wd-index-anchor.vue')['default']
}
}

View File

@@ -2,8 +2,8 @@
"id": "wot-design-uni",
"name": "wot-design-uni",
"displayName": "wot-design-uni 基于vue3+Typescript的高颜值组件库",
"version": "1.2.19",
"description": "一个基于Vue3+TS开发的uni-app组件库提供60+高质量组件,支持暗黑模式、国际化和自定义主题。",
"version": "1.2.24",
"description": "一个基于Vue3+TS开发的uni-app组件库提供70+高质量组件,支持暗黑模式、国际化和自定义主题。",
"keywords": [
"wot-design-uni",
"国际化",
@@ -42,7 +42,8 @@
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
"aliyun": "y",
"alipay": "n"
},
"client": {
"Vue": {

View File

@@ -1,5 +1,5 @@
<p align="center">
<img alt="logo" src="https://wot-design-uni.gitee.io/wot-design.png" width="200">
<img alt="logo" src="https://wot-design-uni.pages.dev/wot-design.png" width="200">
</p>
<h1 align="center">Wot Design Uni</h1>
@@ -39,15 +39,16 @@
</p>
<p align="center">
✈️ <a href="https://wot-design-uni.gitee.io">文档网站 (国内推荐)</a>&nbsp;
✈️ <a href="https://wot-design-uni.pages.dev/">文档网站 (推荐)</a>&nbsp;
🚀 <a href="https://wot-design-uni.cn">文档网站 (备用)</a>&nbsp;
🔥 <a href="https://wot-design-uni.netlify.app">文档网站 (备用)</a>
🔥 <a href="https://wot-design-uni.netlify.app/">文档网站 (备用)</a>&nbsp;
🚫 <a href="https://wot-design-uni.gitee.io/">文档网站 (Gitee暂时下线)</a>
</p>
## ✨ 特性
- 🎯 多平台覆盖,支持 微信小程序、支付宝小程序、钉钉小程序、H5、APP 等.
- 🚀 60+ 个高质量组件,覆盖移动端主流场景.
- 🚀 70+ 个高质量组件,覆盖移动端主流场景.
- 💪 使用 Typescript 构建,提供良好的组件类型系统.
- 🌍 支持国际化,内置 6 种语言包.
- 📖 提供丰富的文档和组件示例.
@@ -59,23 +60,23 @@
扫描二维码访问演示注意因微信审核机制限制当前的微信小程序示例可能不是最新版本可以clone代码到本地预览。
<p>
<img src="https://wot-design-uni.gitee.io/wx.jpg" width="200" height="200" style="margin-right:30px"/>
<img src="https://wot-design-uni.gitee.io/alipay.png" width="200" height="200" />
<img src="https://wot-design-uni.pages.dev/wx.jpg" width="200" height="200" style="margin-right:30px"/>
<img src="https://wot-design-uni.pages.dev/alipay.png" width="200" height="200" />
</p>
## 快速上手
详细说明见 [快速上手](https://wot-design-uni.gitee.io/guide/quick-use.html)。
详细说明见 [快速上手](https://wot-design-uni.pages.dev/guide/quick-use.html)。
## 链接
* [意见反馈](https://github.com/Moonofweisheng/wot-design-uni/issues)
* [更新日志](https://wot-design-uni.gitee.io/guide/changelog.html)
* [常见问题](https://wot-design-uni.gitee.io/guide/common-problems.html)
* [更新日志](https://wot-design-uni.pages.dev/guide/changelog.html)
* [常见问题](https://wot-design-uni.pages.dev/guide/common-problems.html)
* [Discussions 讨论区](https://github.com/Moonofweisheng/wot-design-uni/discussions)
* [QQ 群](https://qm.qq.com/cgi-bin/qm/qr?k=O1Z3pal6StL39qHtABqR54Tb56igr90O&jump_from=webapi&authKey=MtVWfi/EQbT03wW7tKXv4bmyKYHBHtzI8VewlzSsOdxFjN0wbgNy17np9Z9yC4Z8)
* [快速上手项目](https://github.com/Moonofweisheng/wot-starter)
* [Vue3路由库](https://wot-design-uni.gitee.io/uni-mini-router/)
* [Vue3路由库](https://wot-design-uni.pages.dev/uni-mini-router/)
## 开发计划
@@ -107,10 +108,10 @@
### 扫码捐赠
<p>
<img src="https://wot-design-uni.gitee.io/weixinQrcode.jpg" width="200" height="200" style="margin-right:30px"/>
<img src="https://wot-design-uni.gitee.io/alipayQrcode.jpg" width="200" height="200" />
<img src="https://wot-design-uni.pages.dev/weixinQrcode.jpg" width="200" height="200" style="margin-right:30px"/>
<img src="https://wot-design-uni.pages.dev/alipayQrcode.jpg" width="200" height="200" />
</p>
## LICENSE
[MIT](https://github.com/Moonofweisheng/wot-design-uni/blob/develop/LICENSE)
[MIT](https://github.com/Moonofweisheng/wot-design-uni/blob/master/LICENSE)

View File

@@ -1,4 +1,4 @@
const baseUrl = 'http://127.0.0.1:8001';
const baseUrl = 'http://192.168.43.34:8001';
export default {
//微信APPID