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

View File

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

View File

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

View File

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

View File

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