Merge pull request #66 from JeremyYu-cn/feat-upgrade-vue3

Feat: convert common components to composition API
This commit is contained in:
Jeremy Yu 2024-03-05 11:28:29 +00:00 committed by GitHub
commit 01fedbea24
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 171 additions and 143 deletions

View File

@ -13,28 +13,21 @@
</el-popover>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script lang="ts" setup>
import { defineProps } from 'vue'
export default defineComponent({
props: {
title: {
default: '',
},
width: {
default: 0,
},
content: {
default: '',
},
// top/top-start/top-end/bottom/bottom-start/bottom-end/left/left-start/left-end/right/right-start/right-end
position: {
default: 'bottom',
},
// offset: {
// default: 0,
// },
},
setup() {},
type TProps = {
title: string
width: number
content: string
position: "bottom" | "auto" | "auto-start" | "auto-end" | "top" | "right" | "left" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end"
offset?: number
}
const { title, width, content, position } = withDefaults(defineProps<TProps>(), {
title: '',
width: 0,
content: '',
position: 'bottom'
})
</script>

View File

@ -2,8 +2,8 @@
* @Author: ShawnPhang
* @Date: 2021-12-28 09:29:42
* @Description: 百分比进度条
* @LastEditors: ShawnPhang <site: book.palxp.com>
* @LastEditTime: 2023-07-13 23:05:29
* @LastEditors: ShawnPhang <site: book.palxp.com>, Jeremy Yu <https://github.com/JeremyYu-cn>
* @Date: 2024-03-05 10:50:00
-->
<template>
<div v-if="percent" class="mask">
@ -16,33 +16,45 @@
</div>
</template>
<script lang="ts">
import { defineComponent, watch } from 'vue'
<script lang="ts" setup>
import { watch, defineProps, defineEmits } from 'vue'
import { ElProgress } from 'element-plus'
export default defineComponent({
components: { ElProgress },
props: ['percent', 'text', 'cancelText', 'msg'],
emits: ['done', 'cancel'],
setup(props, context) {
watch(
() => props.percent,
(num) => {
if (num >= 100) {
setTimeout(() => {
context.emit('done')
}, 1000)
}
},
)
type TProps = {
percent: number
text: string
cancelText: string
msg: string
}
const cancel = () => {
context.emit('cancel')
type TEmits = {
(event: 'done'): void
(event: 'cancel'): void
}
const {percent, text, cancelText, msg} = defineProps<TProps>()
const emit = defineEmits<TEmits>()
watch(
() => percent,
(num) => {
if (num >= 100) {
setTimeout(() => {
emit('done')
}, 1000)
}
return { cancel }
},
)
const cancel = () => {
emit('cancel')
}
defineExpose({
cancel
})
</script>
<style lang="less" scoped>

View File

@ -2,8 +2,8 @@
* @Author: ShawnPhang
* @Date: 2021-08-29 18:17:13
* @Description: 二次封装上传组件
* @LastEditors: ShawnPhang <https://m.palxp.cn>
* @LastEditTime: 2023-10-05 15:46:02
* @LastEditors: ShawnPhang <https://m.palxp.cn>, Jeremy Yu <https://github.com/JeremyYu-cn>
* @Date: 2024-03-05 10:50:00
-->
<template>
<el-upload action="" accept="image/*" :http-request="upload" :show-file-list="false" multiple>
@ -13,115 +13,135 @@
</el-upload>
</template>
<script lang="ts">
import { defineComponent, onMounted, nextTick } from 'vue'
import { ElUpload } from 'element-plus'
<script lang="ts" setup>
import { onMounted, nextTick, defineProps, withDefaults, defineEmits } from 'vue'
import { ElUpload, UploadRequestOptions } from 'element-plus'
import Qiniu from '@/common/methods/QiNiu'
import { getImage } from '@/common/methods/getImgDetail'
import _config from '@/config'
import useNotification from '@/common/methods/notification'
export default defineComponent({
components: { ElUpload },
props: {
modelValue: {},
options: {
default: () => {
return { bucket: 'xp-design', prePath: 'user' }
},
},
hold: {
default: false, //
},
},
emits: ['done', 'update:modelValue', 'load'],
setup(props, context) {
let uploading: boolean = false // Flag
let timer: any = null
type TModelData = {
num?: string | number
ratio?: string
}
let uploadList: any[] = [] //
let index: number = 0 //
let count: number = 0 //
type TUploadDoneData = {
width: number
height: number
url: string
}
let tempSimpleRes: any = null //
type TQiNiuUploadReturn = { hash: string, key: string }
onMounted(async () => {
await nextTick()
setTimeout(() => {
//
const link_element = document.createElement('script')
link_element.setAttribute('src', _config.QINIUYUN_PLUGIN)
document.head.appendChild(link_element)
}, 1000)
})
type TProps = {
modelValue: TModelData
options: { bucket: string, prePath: string }
hold: boolean
}
const upload = ({ file }: any) => {
if (props.hold) {
context.emit('load', file)
return
}
uploadList.push(file)
clearTimeout(timer)
count++
type TEmits = {
(event: 'done', data: TUploadDoneData): void
(event: 'update:modelValue', data: TModelData): void
(event: 'load', data: File): void
}
const props = withDefaults(defineProps<TProps>(), {
modelValue: () => ({}),
options: () => ({ bucket: 'xp-design', prePath: 'user' }),
hold: false
})
const emit = defineEmits<TEmits>()
let uploading: boolean = false // Flag
let timer: number
let uploadList: File[] = [] //
let index: number = 0 //
let count: number = 0 //
let tempSimpleRes: TQiNiuUploadReturn | null //
onMounted(async () => {
await nextTick()
setTimeout(() => {
//
const link_element = document.createElement('script')
link_element.setAttribute('src', _config.QINIUYUN_PLUGIN)
document.head.appendChild(link_element)
}, 1000)
})
const upload = async ({ file }: UploadRequestOptions) => {
if (props.hold) {
emit('load', file)
return
}
uploadList.push(file)
clearTimeout(timer)
count++
updatePercent(null)
uploadQueue()
}
//
const uploadQueue = async () => {
if (!uploading) {
uploading = true
const file = uploadList[0]
if (file) {
if (file.size <= 1024 * 1024) {
tempSimpleRes = await qiNiuUpload(file) //
console.log("tempSimpleRes", tempSimpleRes)
const { width, height } = await getImage(file)
useNotification('上传成功', '公共测试账户,上传请注意保护隐私哦!', { position: 'bottom-left' })
emit('done', { width, height, url: _config.IMG_URL + tempSimpleRes?.key }) //
} else useNotification('爱护小水管', '请上传小于 1M 的图片哦!', { type: 'error', position: 'bottom-left' })
uploading = false
handleRemove() //
index++
updatePercent(null)
uploadQueue()
} else {
uploading = false
timer = setTimeout(() => {
index = count = 0
updatePercent(0)
}, 3000)
}
//
const uploadQueue = async () => {
if (!uploading) {
uploading = true
const file = uploadList[0]
if (file) {
if (file.size <= 1024 * 1024) {
tempSimpleRes = await qiNiuUpload(file) //
const { width, height }: any = await getImage(file)
useNotification('上传成功', '公共测试账户,上传请注意保护隐私哦!', { position: 'bottom-left' })
context.emit('done', { width, height, url: _config.IMG_URL + tempSimpleRes.key }) //
} else useNotification('爱护小水管', '请上传小于 1M 的图片哦!', { type: 'error', position: 'bottom-left' })
uploading = false
handleRemove() //
index++
updatePercent(null)
uploadQueue()
} else {
uploading = false
timer = setTimeout(() => {
index = count = 0
updatePercent(0)
}, 3000)
}
}
}
const qiNiuUpload = async (file: File) => {
updatePercent(0)
return new Promise(async (resolve: Function) => {
if (props.hold) {
context.emit('load', file)
resolve()
} else {
const result: any = await Qiniu.upload(file, props.options, (res: Type.Object) => {
updatePercent(res.total.percent)
})
resolve(result)
}
})
}
//
const updatePercent = (p?: number | null) => {
const num = typeof p === 'number' ? String(p) : p
const percent = { ...props.modelValue }
percent.num = num ? Number(num).toFixed(0) : percent.num
percent.ratio = count ? `${index} / ${count}` : ''
context.emit('update:modelValue', percent)
}
const handleRemove = () => {
uploadList.length > 0 && uploadList.splice(0, 1)
}
}
}
return {
upload,
const qiNiuUpload = async (file: File): Promise<null | TQiNiuUploadReturn> => {
updatePercent(0)
return new Promise(async (resolve) => {
if (props.hold) {
emit('load', file)
resolve(null)
} else {
const result = await Qiniu.upload(file, props.options, (res: Type.Object) => {
updatePercent(res.total.percent)
})
resolve(result)
}
},
})
}
//
const updatePercent = (p?: number | null) => {
const num = typeof p === 'number' ? String(p) : p
const percent = { ...props.modelValue }
percent.num = num ? Number(num).toFixed(0) : percent.num
percent.ratio = count ? `${index} / ${count}` : ''
emit('update:modelValue', percent)
}
const handleRemove = () => {
uploadList.length > 0 && uploadList.splice(0, 1)
}
defineExpose({
upload,
})
</script>

View File

@ -5,6 +5,8 @@
* @LastEditors: ShawnPhang
* @LastEditTime: 2022-04-08 10:28:47
*/
import { App } from "vue"
function capitalizeFirstLetter(string: string) {
return string.charAt(0).toUpperCase() + string.slice(1)
}
@ -18,7 +20,7 @@ const regex = RegExp('.*^(?!.*?(' + exclude.join('|') + ')).*\\.vue$')
const requireComponent = import.meta.glob('./**/*.vue', { eager: true })
function guide(Vue: Type.Object) {
function guide(Vue: App) {
for (const fileName in requireComponent) {
if (regex.test(fileName)) {
const componentConfig = requireComponent[fileName]

View File

@ -34,6 +34,7 @@ interface IQiniuSubscribeCb {
(result: {
total: { percent: number }
key: string
hash: string
}): void
}