mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-15 16:02:19 +08:00
Merge pull request #66 from JeremyYu-cn/feat-upgrade-vue3
Feat: convert common components to composition API
This commit is contained in:
commit
01fedbea24
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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]
|
||||
|
1
src/types/global.d.ts
vendored
1
src/types/global.d.ts
vendored
@ -34,6 +34,7 @@ interface IQiniuSubscribeCb {
|
||||
(result: {
|
||||
total: { percent: number }
|
||||
key: string
|
||||
hash: string
|
||||
}): void
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user