更新:登录功能

This commit is contained in:
2025-11-04 12:37:04 +08:00
commit a21fb92916
897 changed files with 51500 additions and 0 deletions

View File

@@ -0,0 +1,148 @@
@import '../common/abstracts/_mixin.scss';
@import '../common/abstracts/variable.scss';
.wot-theme-dark {
@include b(search) {
background: $-dark-background4;
@include e(block) {
background-color: $-dark-background;
}
@include e(input) {
color: $-dark-color;
}
@include e(cover) {
background-color: $-dark-background;
}
@include e(search-icon) {
color: $-dark-color;
}
@include e(search-left-icon) {
color: $-dark-color;
}
@include e(clear) {
color: $-dark-color;
}
@include e(cancel) {
color: $-dark-color;
}
@include when(light) {
background: $-dark-background4;
.wd-search__block {
background: $-dark-background7;
}
.wd-search__cover {
background: $-dark-background7;
}
}
}
}
@include b(search) {
display: flex;
padding: $-search-padding;
align-items: center;
background: #fff;
@include e(block) {
flex: 1;
background-color: $-search-input-bg;
border-radius: $-search-input-radius;
display: flex;
flex-direction: row;
align-items: center;
position: relative;
}
@include e(field) {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
position: relative;
}
@include e(input) {
flex: 1;
height: $-search-input-height;
box-sizing: border-box;
padding: $-search-input-padding;
border: none;
background: transparent;
font-size: $-search-input-fs;
-webkit-appearance: none;
outline: none;
color: $-search-input-color;
z-index: 0;
@include lineEllipsis;
&::-webkit-search-cancel-button {
-webkit-appearance: none;
}
}
@include e(cover) {
width: 100%;
height: $-search-input-height;
background-color: $-search-input-bg;
line-height: $-search-input-height;
font-size: $-search-input-fs;
border-radius: $-search-input-radius;
flex-direction: row;
justify-content: center;
align-items: center;
}
@include edeep(search-icon) {
margin-right: 8px;
color: $-search-icon-color;
font-size: $-search-icon-size;
}
@include edeep(search-left-icon) {
position: absolute;
font-size: $-search-icon-size;
top: 50%;
left: 16px;
transform: translateY(-50%);
color: $-search-icon-color;
}
@include e(placeholder-txt) {
color: $-search-placeholder-color;
font-size: $-search-input-fs;
}
@include edeep(clear) {
position: absolute;
right: 0;
padding: 6px 9px 6px 7px;
color: $-search-cancel-color;
}
@include edeep(clear-icon) {
vertical-align: middle;
font-size: $-search-clear-icon-size;
}
@include e(cancel) {
padding: $-search-cancel-padding;
height: $-search-input-height;
line-height: $-search-input-height;
font-size: $-search-cancel-fs;
color: $-search-cancel-color;
-webkit-tap-highlight-color: transparent;
}
@include when(light) {
background: $-search-light-bg;
.wd-search__block {
background: #fff;
}
.wd-search__cover {
background: #fff;
}
}
@include when(without-cancel) {
padding-right: $-search-side-padding;
}
}

View File

@@ -0,0 +1,102 @@
/*
* @Author: weisheng
* @Date: 2024-09-01 15:42:04
* @LastEditTime: 2024-09-21 15:36:09
* @LastEditors: weisheng
* @Description:
* @FilePath: \wot-design-uni\src\uni_modules\wot-design-uni\components\wd-search\types.ts
* 记得注释
*/
import { baseProps, makeBooleanProp, makeNumberProp, makeNumericProp, makeStringProp } from '../common/props'
export const searchProps = {
...baseProps,
customInputClass: makeStringProp(''),
/**
* 输入框内容,双向绑定
* 类型: string
* 默认值: ''
*/
modelValue: makeStringProp(''),
/**
* 是否使用输入框右侧插槽
* 类型: boolean
* 默认值: false
* @deprecated 该属性已废弃将在下一个minor版本被移除直接使用插槽即可
*/
useSuffixSlot: makeBooleanProp(false),
/**
* 搜索框占位文本
* 类型: string
*/
placeholder: String,
/**
* 搜索框右侧文本
* 类型: string
*/
cancelTxt: String,
/**
* 搜索框亮色(白色)
* 类型: boolean
* 默认值: false
*/
light: makeBooleanProp(false),
/**
* 是否隐藏右侧文本
* 类型: boolean
* 默认值: false
*/
hideCancel: makeBooleanProp(false),
/**
* 是否禁用搜索框
* 类型: boolean
* 默认值: false
*/
disabled: makeBooleanProp(false),
/**
* 原生属性,设置最大长度。-1 表示无限制
* 类型: string / number
* 默认值: -1
*/
maxlength: makeNumberProp(-1),
/**
* placeholder 居左边
* 类型: boolean
* 默认值: false
*/
placeholderLeft: makeBooleanProp(false),
/**
* 是否自动聚焦
* 类型: boolean
* 默认值: false
* 最低版本: 0.1.63
*/
focus: makeBooleanProp(false),
/**
* 是否在点击清除按钮时聚焦输入框
* 类型: boolean
* 默认值: false
* 最低版本: 0.1.63
*/
focusWhenClear: makeBooleanProp(false),
/**
* 原生属性,指定 placeholder 的样式目前仅支持color,font-size和font-weight
*/
placeholderStyle: String,
/**
* 原生属性,指定 placeholder 的样式类
*/
placeholderClass: makeStringProp('')
}

View File

@@ -0,0 +1,187 @@
<template>
<view :class="rootClass" :style="customStyle">
<view class="wd-search__block">
<slot name="prefix"></slot>
<view class="wd-search__field">
<view v-if="!placeholderLeft" :style="coverStyle" class="wd-search__cover" @click="closeCover">
<wd-icon name="search" custom-class="wd-search__search-icon"></wd-icon>
<text :class="`wd-search__placeholder-txt ${placeholderClass}`">{{ placeholder || translate('search') }}</text>
</view>
<wd-icon v-if="showInput || inputValue || placeholderLeft" name="search" custom-class="wd-search__search-left-icon"></wd-icon>
<input
v-if="showInput || inputValue || placeholderLeft"
:placeholder="placeholder || translate('search')"
:placeholder-class="`wd-search__placeholder-txt ${placeholderClass}`"
:placeholder-style="placeholderStyle"
confirm-type="search"
v-model="inputValue"
:class="['wd-search__input', customInputClass]"
@focus="handleFocus"
@input="handleInput"
@blur="handleBlur"
@confirm="handleConfirm"
:disabled="disabled"
:maxlength="maxlength"
:focus="isFocused"
/>
<wd-icon v-if="inputValue" custom-class="wd-search__clear wd-search__clear-icon" name="error-fill" @click="handleClear" />
</view>
</view>
<slot v-if="!hideCancel" name="suffix">
<view class="wd-search__cancel" @click="handleCancel">
{{ cancelTxt || translate('cancel') }}
</view>
</slot>
</view>
</template>
<script lang="ts">
export default {
name: 'wd-search',
options: {
virtualHost: true,
addGlobalClass: true,
styleIsolation: 'shared'
}
}
</script>
<script lang="ts" setup>
import wdIcon from '../wd-icon/wd-icon.vue'
import { type CSSProperties, computed, onMounted, ref, watch } from 'vue'
import { objToStyle, pause } from '../common/util'
import { useTranslate } from '../composables/useTranslate'
import { searchProps } from './types'
const props = defineProps(searchProps)
const emit = defineEmits(['update:modelValue', 'change', 'clear', 'search', 'focus', 'blur', 'cancel'])
const { translate } = useTranslate('search')
const isFocused = ref<boolean>(false) // 是否聚焦中
const showInput = ref<boolean>(false) // 是否显示输入框 用于实现聚焦的hack
const inputValue = ref<string>('') // 输入框的值
const showPlaceHolder = ref<boolean>(true)
const clearing = ref<boolean>(false)
watch(
() => props.modelValue,
(newValue) => {
inputValue.value = newValue
if (newValue) {
showInput.value = true
}
},
{ immediate: true }
)
watch(
() => props.focus,
(newValue) => {
if (newValue) {
if (props.disabled) return
closeCover()
}
}
)
onMounted(() => {
if (props.focus) {
closeCover()
}
})
const rootClass = computed(() => {
return `wd-search ${props.light ? 'is-light' : ''} ${props.hideCancel ? 'is-without-cancel' : ''} ${props.customClass}`
})
const coverStyle = computed(() => {
const coverStyle: CSSProperties = {
display: inputValue.value === '' && showPlaceHolder.value ? 'flex' : 'none'
}
return objToStyle(coverStyle)
})
async function hackFocus(focus: boolean) {
showInput.value = focus
await pause()
isFocused.value = focus
}
async function closeCover() {
if (props.disabled) return
await pause(100)
showPlaceHolder.value = false
hackFocus(true)
}
function handleInput(event: any) {
inputValue.value = event.detail.value
emit('update:modelValue', event.detail.value)
emit('change', {
value: event.detail.value
})
}
async function handleClear() {
inputValue.value = ''
if (props.focusWhenClear) {
clearing.value = true
isFocused.value = false
}
await pause()
if (props.focusWhenClear) {
showPlaceHolder.value = false
hackFocus(true)
} else {
showPlaceHolder.value = true
hackFocus(false)
}
emit('change', {
value: ''
})
emit('update:modelValue', '')
emit('clear')
}
function handleConfirm({ detail: { value } }: any) {
// 组件触发search事件
emit('search', {
value
})
}
function handleFocus() {
showPlaceHolder.value = false
emit('focus', {
value: inputValue.value
})
}
async function handleBlur() {
// 等待150毫秒clear执行完毕
await pause(150)
if (clearing.value) {
clearing.value = false
return
}
// 组件触发blur事件
showPlaceHolder.value = !inputValue.value
showInput.value = !showPlaceHolder.value
isFocused.value = false
emit('blur', {
value: inputValue.value
})
}
function handleCancel() {
emit('cancel', {
value: inputValue.value
})
}
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>