前言:
此时朋友们对“mysqluuiduuid”大致比较看重,看官们都需要学习一些“mysqluuiduuid”的相关资讯。那么小编在网络上网罗了一些对于“mysqluuiduuid””的相关文章,希望各位老铁们能喜欢,朋友们快快来学习一下吧!上一小节我们详细讲述了 uni-app全栈开发vite环境及插件配置管理 。接下来我们需要对我们的项目工程 uniapp-demo 做一个结构划分,分类存放我们的工程文件
1、自动注入全局 API ,避免繁琐的API引入
//根目录创建declare文件,存放auto-imports.d.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:52:03 * @Description: 自动注入全局API * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/declare global { const app: typeof import('@/app/index')['app'] const assert: typeof import('power-assert')['default'] const computed: typeof import('vue')['computed'] const createApp: typeof import('vue')['createApp'] const customRef: typeof import('vue')['customRef'] const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] const defineComponent: typeof import('vue')['defineComponent'] const effectScope: typeof import('vue')['effectScope'] const EffectScope: typeof import('vue')['EffectScope'] const getCurrentInstance: typeof import('vue')['getCurrentInstance'] const getCurrentScope: typeof import('vue')['getCurrentScope'] const h: typeof import('vue')['h'] const inject: typeof import('vue')['inject'] const isReadonly: typeof import('vue')['isReadonly'] const isRef: typeof import('vue')['isRef'] const markRaw: typeof import('vue')['markRaw'] const nextTick: typeof import('vue')['nextTick'] const onActivated: typeof import('vue')['onActivated'] const onAddToFavorites: typeof import('@dcloudio/uni-app')['onAddToFavorites'] const onBackPress: typeof import('@dcloudio/uni-app')['onBackPress'] const onBeforeMount: typeof import('vue')['onBeforeMount'] const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] const onDeactivated: typeof import('vue')['onDeactivated'] const onError: typeof import('@dcloudio/uni-app')['onError'] const onErrorCaptured: typeof import('vue')['onErrorCaptured'] const onHide: typeof import('@dcloudio/uni-app')['onHide'] const onLaunch: typeof import('@dcloudio/uni-app')['onLaunch'] const onLoad: typeof import('@dcloudio/uni-app')['onLoad'] const onMounted: typeof import('vue')['onMounted'] const onNavigationBarButtonTap: typeof import('@dcloudio/uni-app')['onNavigationBarButtonTap'] const onNavigationBarSearchInputChanged: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputChanged'] const onNavigationBarSearchInputClicked: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputClicked'] const onNavigationBarSearchInputConfirmed: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputConfirmed'] const onNavigationBarSearchInputFocusChanged: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputFocusChanged'] const onPageNotFound: typeof import('@dcloudio/uni-app')['onPageNotFound'] const onPageScroll: typeof import('@dcloudio/uni-app')['onPageScroll'] const onPullDownRefresh: typeof import('@dcloudio/uni-app')['onPullDownRefresh'] const onReachBottom: typeof import('@dcloudio/uni-app')['onReachBottom'] const onReady: typeof import('@dcloudio/uni-app')['onReady'] const onRenderTracked: typeof import('vue')['onRenderTracked'] const onRenderTriggered: typeof import('vue')['onRenderTriggered'] const onResize: typeof import('@dcloudio/uni-app')['onResize'] const onScopeDispose: typeof import('vue')['onScopeDispose'] const onServerPrefetch: typeof import('vue')['onServerPrefetch'] const onShareAppMessage: typeof import('@dcloudio/uni-app')['onShareAppMessage'] const onShareTimeline: typeof import('@dcloudio/uni-app')['onShareTimeline'] const onShow: typeof import('@dcloudio/uni-app')['onShow'] const onTabItemTap: typeof import('@dcloudio/uni-app')['onTabItemTap'] const onThemeChange: typeof import('@dcloudio/uni-app')['onThemeChange'] const onUnhandledRejection: typeof import('@dcloudio/uni-app')['onUnhandledRejection'] const onUnload: typeof import('@dcloudio/uni-app')['onUnload'] const onUnmounted: typeof import('vue')['onUnmounted'] const onUpdated: typeof import('vue')['onUpdated'] const provide: typeof import('vue')['provide'] const reactive: typeof import('vue')['reactive'] const readonly: typeof import('vue')['readonly'] const ref: typeof import('vue')['ref'] const resolveComponent: typeof import('vue')['resolveComponent'] const ScrollSymbol: typeof import('@/hooks')['ScrollSymbol'] const shallowReactive: typeof import('vue')['shallowReactive'] const shallowReadonly: typeof import('vue')['shallowReadonly'] const shallowRef: typeof import('vue')['shallowRef'] const toRaw: typeof import('vue')['toRaw'] const toRef: typeof import('vue')['toRef'] const toRefs: typeof import('vue')['toRefs'] const triggerRef: typeof import('vue')['triggerRef'] const unref: typeof import('vue')['unref'] const useAttrs: typeof import('vue')['useAttrs'] const useCssModule: typeof import('vue')['useCssModule'] const useCssVars: typeof import('vue')['useCssVars'] const useQuery: typeof import('@/hooks')['useQuery'] const useScroll: typeof import('@/hooks')['useScroll'] const useSlots: typeof import('vue')['useSlots'] const watch: typeof import('vue')['watch'] const watchEffect: typeof import('vue')['watchEffect']}export {}//注意:在上一节 imports.config.ts 文件导出全局配置dts: 'declare/auto-imports.d.ts',
2、完善src文件工程结构
src下创建store文件,并完善工程文件(状态管理)
//新建src/store/index.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:04:03 * @Description: 请求封装 * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/import { InjectionKey} from 'vue'import { createStore } from 'vuex'import { store as app, AppState, AppStore } from '@/store/modules/app'import getters from './getters'export const key: InjectionKey<Store> = Symbol()export interface RootState { app: AppState}export type Store = AppStore<Pick<RootState, 'app'>>export const store = createStore<RootState>({ modules: { app }, getters})export function useStore(): Store { return store as Store}
//新建src/store/getters.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:15:22 * @Description: 请求封装 * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/import { RootState } from '@/store'export default { token: (state: RootState) => state.app.token,}
//新建modules src/store/modules/app/index.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:19:59 * @Description: 请求封装 * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/import { Store as VuexStore, CommitOptions, DispatchOptions, Module } from 'vuex'import { RootState } from '@/store'import { state } from './state'import { actions, Actions } from './ations'import { mutations, Mutations } from './mutations'import type { AppState } from './state'export { AppState }export type AppStore<S = AppState> = Omit<VuexStore<S>, 'getters' | 'commit' | 'dispatch'> & { commit<K extends keyof Mutations, P extends Parameters<Mutations[K]>[1]>( key: K, payload: P, options?: CommitOptions ): ReturnType<Mutations[K]>} & { dispatch<K extends keyof Actions>( key: K, payload: Parameters<Actions[K]>[1], options?: DispatchOptions ): ReturnType<Actions[K]>}export const store: Module<AppState, RootState> = { state, actions, mutations,}
//新建modules src/store/modules/app/state.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:19:59 * @Description: state * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/import {reactive} from 'vue'export interface AppState { token: string, num:number, userData: Array<any>}export const state: AppState = reactive({ token: '', num:0, userData:{}})
//新建modules src/store/modules/app/action-types.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:22:12 * @Description: action-types类型约束 * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/export enum AppActionTypes { ACTION_LOGIN = 'ACTION_LOGIN', CLEAR_TOKEN = 'CLEAR_TOKEN', EDIT_USER_MSG = 'EDIT_USER_MSG', SET_NUM = 'SET_NUM'}
//新建modules src/store/modules/app/action.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:20:58 * @Description: action * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/import { ActionTree, ActionContext } from 'vuex'import { RootState } from '@/store'import { AppState } from './state'import { Mutations } from './mutations'import { AppActionTypes } from './action-types'import { AppMutationTypes } from './mutation-types'type AugmentedActionContext = { commit<K extends keyof Mutations>(key: K, payload: Parameters<Mutations[K]>[1]): ReturnType<Mutations[K]>} & Omit<ActionContext<AppState, RootState>, 'commit'>// export interface Actions {// [AppActionTypes.ACTION_RESET_TOKEN]({ commit }: AugmentedActionContext): void// }export const actions: ActionTree<AppState, RootState> & Actions = { [AppActionTypes.ACTION_LOGIN]({ commit }: AugmentedActionContext, userData: object) { commit(AppMutationTypes.SET_USER_MSG, userData) }, [AppActionTypes.CLEAR_TOKEN]({ commit }: AugmentedActionContext) { commit(AppMutationTypes.CLEAR_USER, null) }, [AppActionTypes.CLEAR_TOKEN]({ commit }: AugmentedActionContext,userData: object) { commit(AppMutationTypes.CLEAR_TOKEN, userData) }, [AppActionTypes.SET_NUM]({ commit }: AugmentedActionContext,num: number) { commit(AppMutationTypes.SET_NUM, num) }, }
//新建modules src/store/modules/app/mutation-types.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:22:12 * @Description: mutation-types类型约束 * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/export enum AppMutationTypes { SET_USER_MSG = 'SET_USER_MSG', CLEAR_TOKEN = 'CLEAR_TOKEN', EDIT_USER_MSG = 'EDIT_USER_MSG', SET_NUM = 'SET_NUM'}
//新建modules src/store/modules/app/mutation.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:22:12 * @Description: mutation * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/import { MutationTree } from 'vuex'import { AppState } from './state'import { AppMutationTypes } from './mutation-types'export type Mutations<S = AppState> = { [AppMutationTypes.SET_TOKEN](state: S, token: string): void}export const mutations: MutationTree<AppState> & Mutations = { [AppMutationTypes.SET_USER_MSG](state: AppState, userData: object) { state.userData = userData }, [AppMutationTypes.CLEAR_USER](state: AppState) { state.userData = null }, [AppMutationTypes.CLEAR_TOKEN](state: AppState, userData: object) { state.userData = userData }, [AppMutationTypes.SET_NUM](state: AppState, num: number) { state.num = num } }
src下创建type文件,并完善工程文件(约束类)
//例如:分页参数,根据业务需要自行补充export interface PageParams { data?: any id?: string from?: string}
src下创建styles文件,并完善工程文件(css样式)
//例如:styles/theme.scsspage { --theme-color: #9ac2ff;}//例如:styles/index.scss@import './theme.scss'; //引入theme.scss
src下创建components文件,并完善工程文件(组件管理)
//例如:components/drag-image.vue<template> <view class="con"> <template v-if="viewWidth"> <movable-area v-if="show" class="area" :style="{ height: areaHeight }" @mouseenter="mouseenter" @mouseleave="mouseleave"> <text v-if='imageList.length>0' class="tips_img">主</text> <movable-view v-for="(item, index) in imageList" :key="item.id" class="view" direction="all" :y="item.y" :x="item.x" :damping="40" :disabled="item.disable" @change="onChange($event, item)" @touchstart="touchstart(item)" @mousedown="touchstart(item)" @touchend="touchend(item)" @mouseup="touchend(item)" :style="{ width: viewWidth + 'px', height: viewWidth + 'px', 'z-index': item.zIndex, opacity: item.opacity }"> <view class="area-con" :style="{ width: childWidth, height: childWidth, borderRadius: borderRadius + 'rpx', transform: 'scale(' + item.scale + ')' }"> <image class="pre-image" :src="item.src" mode="aspectFill"></image> <view class="del-con" @click="delImages(item, index)" @touchstart.stop="delImageMp(item, index)" @touchend.stop="nothing()" @mousedown.stop="nothing()" @mouseup.stop="nothing()"> <view class="del-wrap"> <image class="del-image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhCAYAAABX5MJvAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAhdEVYdENyZWF0aW9uIFRpbWUAMjAyMDowNzoyNSAyMTo1NDoyOU4TkJAAAADcSURBVFhH7ZfRCoMwDEXLvkjwwVf/bH/emmAyN6glTW9WBjsgwm28OeCLpj81Sil7zvlJ90UiONS/yY5VogsO6XrBg3IEQ5a/s8vRSWUAKmLqp2w5jz5BiNQEGMo3GbloDLtFXJ1IkaEuhAiiY6gEIqB4yqACSk9piIBiKQ8VUFpLviKg3C2rESKgWERCBZSWiEfgIfffYvrrsAgoISJ3Apy3zuTxcSxLQkV6ykNEPKVQkZEyiAiiZKgDIaC4upACSlcn5fM/+WuDCAHF1E/Z/N9AhkMZnPNDPI+UDjPIXgAQIGjNAAAAAElFTkSuQmCC"> </image> </view> </view> </view> </movable-view> <view class="add" v-if="imageList.length < number" :style="{ top: add.y, left: add.x, width: viewWidth + 'px', height: viewWidth + 'px' }" @click="addImages"> <view class="add-wrap" :style="{ width: childWidth, height: childWidth, borderRadius: borderRadius + 'rpx' }"> <image :style="{ width: childWidth, height: childWidth, borderRadius: borderRadius + 'rpx' }" src='/static/images/addimg.png'></image> <!-- <image style="width: 54rpx;height: 54rpx;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA2CAYAAACMRWrdAAABIUlEQVRoQ+2a2w2DMAxFeQzWrsMUbadAsEw3S1CqVgppKwLX8BEOP4iHTXx8uUgWdVXoVhdaV0VhSmf7vr/H8V3XzY6V3P9iD+nYOI5P7/01LMI596AwoZV0TIBXIUWFXhKLFBWYSFGhhxQN6SFFQ5i4ogITKSr0cEVDekjRECauqMBEigq9U7piOk2yAti27SUe5ljlTfPEQ6KZecTvwl4P3ytvOv06R2HDMNzes7+6aRrvnHvtf50L13Lp50rx88zcvNlS3JpwKQ67XyK04nq2nFbk/LqVjin0TvmBNgQ2S4UUDcliHgpMpKjQwxUN6SFFQ5i4ogITKSr0cEVDekjRECauqMAsVoph+hVPtYr5+03p9tbYQ96xrYtT4ootbAJGVxxVTapVswAAAABJRU5ErkJggg=="> </image> --> </view> </view> </movable-area> </template> </view></template><script>export default { emits: ['input', 'update:modelValue'], props: { // 排序图片 value: { type: Array, default: function () { return [] } }, // 排序图片 modelValue: { type: Array, default: function () { return [] } }, // 从 list 元素对象中读取的键名 keyName: { type: String, default: null }, // 选择图片数量限制 number: { type: Number, default: 6 }, // 图片父容器宽度(实际显示的图片宽度为 imageWidth / 1.1 ),单位 rpx // imageWidth > 0 则 cols 无效 imageWidth: { type: Number, default: 0 }, // 图片列数 cols: { type: Number, default: 3 }, // 图片圆角,单位 rpx borderRadius: { type: Number, default: 0 }, // 图片周围空白填充,单位 rpx padding: { type: Number, default: 10 }, // 拖动图片时放大倍数 [0, ∞) scale: { type: Number, default: 1.1 }, // 拖动图片时不透明度 opacity: { type: Number, default: 0.7 }, // 自定义添加 addImage: { type: Function, default: null }, // 删除确认 delImage: { type: Function, default: null } }, data() { return { imageList: [], width: 0, add: { x: 0, y: 0 }, colsValue: 0, viewWidth: 0, tempItem: null, timer: null, changeStatus: true, preStatus: true, first: true, show: true, } }, computed: { areaHeight() { let height = '' // return '285px' if (this.imageList.length < this.number) { height = (Math.ceil((this.imageList.length + 1) / this.colsValue) * this.viewWidth).toFixed() + 'px' } else { height = (Math.ceil(this.imageList.length / this.colsValue) * this.viewWidth).toFixed() + 'px' } console.log('areaHeight', height) return height }, childWidth() { return this.viewWidth - this.rpx2px(this.padding) * 2 + 'px' }, }, watch: { areaHeight() { this.show = false this.$nextTick(() => { this.show = true }) }, value: { handler(n) { if (!this.first && this.changeStatus) { console.log('watch', n) let flag = false for (let i = 0; i < n.length; i++) { if (flag) { this.addProperties(this.getSrc(n[i])) continue } if (this.imageList.length === i || this.imageList[i].src !== this.getSrc(n[i])) { flag = true this.imageList.splice(i) this.addProperties(this.getSrc(n[i])) } } } }, deep: true }, modelValue: { handler(n) { if (!this.first && this.changeStatus) { console.log('watch', n) let flag = false for (let i = 0; i < n.length; i++) { if (flag) { this.addProperties(this.getSrc(n[i])) continue } if (this.imageList.length === i || this.imageList[i].src !== this.getSrc(n[i])) { flag = true this.imageList.splice(i) this.addProperties(this.getSrc(n[i])) } } } }, deep: true }, }, created() { this.width = uni.getSystemInfoSync().windowWidth }, mounted() { const query = uni.createSelectorQuery().in(this) query.select('.con').boundingClientRect(data => { this.colsValue = this.cols this.viewWidth = data.width / this.cols if (this.imageWidth > 0) { this.viewWidth = this.rpx2px(this.imageWidth) this.colsValue = Math.floor(data.width / this.viewWidth) } let list = this.value // #ifdef VUE3 list = this.modelValue // #endif for (let item of list) { this.addProperties(this.getSrc(item)) } this.first = false }) query.exec() }, methods: { getSrc(item) { if (this.keyName !== null) { return item[this.keyName] } return item }, onChange(e, item) { if (!item) return item.oldX = e.detail.x item.oldY = e.detail.y if (e.detail.source === 'touch') { if (item.moveEnd) { item.offset = Math.sqrt(Math.pow(item.oldX - item.absX * this.viewWidth, 2) + Math.pow(item.oldY - item .absY * this.viewWidth, 2)) } let x = Math.floor((e.detail.x + this.viewWidth / 2) / this.viewWidth) if (x >= this.colsValue) return let y = Math.floor((e.detail.y + this.viewWidth / 2) / this.viewWidth) let index = this.colsValue * y + x if (item.index != index && index < this.imageList.length) { this.changeStatus = false for (let obj of this.imageList) { if (item.index > index && obj.index >= index && obj.index < item.index) { this.change(obj, 1) } else if (item.index < index && obj.index <= index && obj.index > item.index) { this.change(obj, -1) } else if (obj.id != item.id) { obj.offset = 0 obj.x = obj.oldX obj.y = obj.oldY setTimeout(() => { this.$nextTick(() => { obj.x = obj.absX * this.viewWidth obj.y = obj.absY * this.viewWidth }) }, 0) } } item.index = index item.absX = x item.absY = y if (!item.moveEnd) { setTimeout(() => { this.$nextTick(() => { item.x = item.absX * this.viewWidth item.y = item.absY * this.viewWidth }) }, 0) } // console.log('bbb', JSON.parse(JSON.stringify(item))); this.sortList() } } }, change(obj, i) { obj.index += i obj.offset = 0 obj.x = obj.oldX obj.y = obj.oldY obj.absX = obj.index % this.colsValue obj.absY = Math.floor(obj.index / this.colsValue) setTimeout(() => { this.$nextTick(() => { obj.x = obj.absX * this.viewWidth obj.y = obj.absY * this.viewWidth }) }, 0) }, touchstart(item) { this.imageList.forEach(v => { v.zIndex = v.index + 9 }) item.zIndex = 99 item.moveEnd = true this.tempItem = item this.timer = setTimeout(() => { item.scale = this.scale item.opacity = this.opacity clearTimeout(this.timer) this.timer = null }, 200) }, touchend(item) { this.previewImage(item) item.scale = 1 item.opacity = 1 item.x = item.oldX item.y = item.oldY item.offset = 0 item.moveEnd = false setTimeout(() => { this.$nextTick(() => { item.x = item.absX * this.viewWidth item.y = item.absY * this.viewWidth this.tempItem = null this.changeStatus = true }) // console.log('ccc', JSON.parse(JSON.stringify(item))); }, 0) this.$emit('resetImg',this.imageList) // console.log('ddd', JSON.parse(JSON.stringify(item))); }, previewImage(item) { if (this.timer && this.preStatus && this.changeStatus && item.offset < 28.28) { clearTimeout(this.timer) this.timer = null const list = this.value || this.modelValue let srcList = [] let numImg = ref(0) this.imageList.map((tab, index) => { srcList.push(item.src) if(tab.src == item.src){ numImg.value = index } }) uni.previewImage({ urls:srcList , current: srcList[numImg], success: () => { this.preStatus = false setTimeout(() => { this.preStatus = true }, 600) }, fail: (e) => { console.log(e); } }) } else if (this.timer) { clearTimeout(this.timer) this.timer = null } }, mouseenter() { //#ifdef H5 this.imageList.forEach(v => { v.disable = false }) //#endif }, mouseleave() { //#ifdef H5 if (this.tempItem) { this.imageList.forEach(v => { v.disable = true v.zIndex = v.index + 9 v.offset = 0 v.moveEnd = false if (v.id == this.tempItem.id) { if (this.timer) { clearTimeout(this.timer) this.timer = null } v.scale = 1 v.opacity = 1 v.x = v.oldX v.y = v.oldY this.$nextTick(() => { v.x = v.absX * this.viewWidth v.y = v.absY * this.viewWidth this.tempItem = null }) } }) this.changeStatus = true } //#endif }, addImages() { this.$emit('choiseImg') // if (typeof this.addImage === 'function') { // this.addImage.bind(this.$parent)() // } else { // let checkNumber = this.number - this.imageList.length // uni.chooseImage({ // count: checkNumber, // sourceType: ['album', 'camera'], // success: res => { // let count = checkNumber <= res.tempFilePaths.length ? checkNumber : res.tempFilePaths.length // for (let i = 0; i < count; i++) { // this.addProperties(res.tempFilePaths[i]) // } // this.sortList() // } // }) // } }, delImages(item, index) { if (typeof this.delImage === 'function') { this.delImage.bind(this.$parent)(() => { this.delImageHandle(item, index) }) } else { this.delImageHandle(item, index) } }, delImageHandle(item, index) { this.imageList.splice(index, 1) this.$emit('resetImg',this.imageList) for (let obj of this.imageList) { if (obj.index > item.index) { obj.index -= 1 obj.x = obj.oldX obj.y = obj.oldY obj.absX = obj.index % this.colsValue obj.absY = Math.floor(obj.index / this.colsValue) this.$nextTick(() => { obj.x = obj.absX * this.viewWidth obj.y = obj.absY * this.viewWidth }) } } this.add.x = (this.imageList.length % this.colsValue) * this.viewWidth + 'px' this.add.y = Math.floor(this.imageList.length / this.colsValue) * this.viewWidth + 'px' this.sortList() }, delImageMp(item, index) { //#ifdef MP this.delImages(item, index) //#endif }, sortList() { console.log('sortList'); const result = [] let source = this.value // #ifdef VUE3 source = this.modelValue // #endif let list = this.imageList.slice() list.sort((a, b) => { return a.index - b.index }) for (let s of list) { let item = source.find(d => this.getSrc(d) == s.src) if (item) { result.push(item) } else { if (this.keyName !== null) { result.push({ [this.keyName]: s.src }) } else { result.push(s.src) } } } this.$emit("input", result); this.$emit("update:modelValue", result); }, addProperties(item) { console.log(item); let absX = this.imageList.length % this.colsValue let absY = Math.floor(this.imageList.length / this.colsValue) let x = absX * this.viewWidth let y = absY * this.viewWidth this.imageList.push({ src: item, x, y, oldX: x, oldY: y, absX, absY, scale: 1, zIndex: 9, opacity: 1, index: this.imageList.length, id: this.guid(16), disable: false, offset: 0, moveEnd: false }) this.add.x = (this.imageList.length % this.colsValue) * this.viewWidth + 'px' this.add.y = Math.floor(this.imageList.length / this.colsValue) * this.viewWidth + 'px' }, nothing() { }, rpx2px(v) { return this.width * v / 750 }, guid(len = 32) { const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('') const uuid = [] const radix = chars.length for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix] uuid.shift() return `u${uuid.join('')}` } }}</script><style lang="scss" scoped>.con { // padding: 30rpx; .area { width: 100%; position: relative; .tips_img{ position: absolute; left:0rpx; top:0rpx; z-index: 999; display: inline-block; width:42rpx; height:42rpx; line-height: 42rpx; text-align: center; border-radius: 50%; font-size: 20rpx; background-color: rgba(0,0,0,.5); color:#fff; } .view { display: flex; justify-content: center; align-items: center; .area-con { position: relative; overflow: hidden; .tips_img{ position: absolute; right:0rpx; bottom:0rpx; z-index: 999; display: inline-block; width:42rpx; height:42rpx; line-height: 42rpx; text-align: center; border-radius: 50%; font-size: 20rpx; background-color: rgba(0,0,0,.5); color:#fff; } .pre-image { width: 100%; height: 100%; } .del-con { position: absolute; top: 0rpx; right: 0rpx; padding: 0 0 20rpx 20rpx; .del-wrap { width: 36rpx; height: 36rpx; background-color: rgba(0, 0, 0, 0.4); border-radius: 0 0 0 10rpx; display: flex; justify-content: center; align-items: center; .del-image { width: 20rpx; height: 20rpx; } } } } } .add { position: absolute; display: flex; justify-content: center; align-items: center; .add-wrap { display: flex; justify-content: center; align-items: center; background-color: #fff; } } }}</style>
src下创建utils文件,并完善工程文件(工具类)
//新建src/utils/requestClass.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:59:03 * @Description: 请求封装requestClass类 * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/const config = Symbol('config')const isCompleteURL = Symbol('isCompleteURL')const requestBefore = Symbol('requestBefore')const requestAfter = Symbol('requestAfter')class requestClass { // 默认配置 [config]: { baseURL?: string } & UniApp.RequestOptions = { baseURL: '', url: '', header: { 'content-type': 'application/x-www-form-urlencoded' }, method: 'GET', timeout: 3000, dataType: 'json', responseType: 'text' } // 拦截器 interceptors = { request: (func: Fn) => { if (func) { requestClass[requestBefore] = func } else { requestClass[requestBefore] = (request) => request } }, response: (func: Fn) => { if (func) { requestClass[requestAfter] = func } else { requestClass[requestAfter] = (response) => response } }, } // 请求之前,是默认配置 static [requestBefore](config: UniApp.RequestOptions) { return config } // 请求之后,默认配置发生改变的话 static [requestAfter](response: any) { return response } // 判断url是否完整 static [isCompleteURL](url: string) { return /(http|https):\/\/([\w.]+\/?)\S*/.test(url) } request(options: UniApp.RequestOptions & { baseURL?: string }) { options.baseURL = options.baseURL || this[config].baseURL options.dataType = options.dataType || this[config].dataType options.url = requestClass[isCompleteURL](options.url) ? options.url : (options.baseURL + options.url) options.data = options.data options.header = { ...options.header, ...this[config].header } options.method = options.method || this[config].method options = { ...options, ...requestClass[requestBefore](options) } return new Promise((resolve, reject) => { options.success = function (res) { resolve(requestClass[requestAfter](res)) } options.fail = function (err) { reject(requestClass[requestAfter](err)) } uni.request(options) // 中断请求实现方法 // let obj: any = {} // obj[request.url] = uni.request(options) // abortRequest() { // for (const key in obj) { // if (Object.prototype.hasOwnProperty.call(obj, key)) { // const element = obj[key]; // element.abort() // } // } // } }) } get(url: string, data: any = {}, options: Recordable = {}) { return this.request({ ...options, url, data, method: 'GET' }) } post(url: string, data: any = {}, options: Recordable = {}) { return this.request({ ...options, url, data, method: 'POST' }) } put(url: string, data: any = {}, options: Recordable = {}) { return this.request({ ...options, url, data, method: 'PUT' }) } delete(url: string, data: any = {}, options: Recordable = {}) { return this.request({ ...options, url, data, method: 'DELETE' }) } getConfig() { return this[config] } // 修改默认配置的一个方法,可以修改请求地址,请求方式等等.. setConfig(func: Fn) { this[config] = func(this[config]) }}export default requestClass
//新建src/utils/request.ts/** * @Author: Mr Chen 陈晓 * @Date: 2023-01-16 14:12:05 * @LastEditTime: 2023-02-09 09:59:03 * @Description: 请求封装request * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 **/import requestClass from './requestClass'import { HTTP_REQUEST_URL_H5, HTTP_REQUEST_URL_APP } from '@/config/app'import { AppActionTypes } from '@/store/modules/app/action-types'import qs from 'qs'import { useStore } from 'vuex'const Request = new requestClass()const platform = uni.getSystemInfoSync().platform// 请求拦截器Request.interceptors.request((request: any) => { request.header['device-os'] = platform if (request.header.contentType) { request.header['content-type'] = request.header.contentType delete request.header.contentType } if(uni.getStorageSync('userData')){ request.header['token'] = uni.getStorageSync('userData').token // request.header['id'] = uni.getStorageSync('userData').id // request.header['uid'] = uni.getStorageSync('userData').userIdBuss // request.header['pid'] = uni.getStorageSync('userData').lmpt_userid } if (request.method === 'GET') { request.data = qs.stringify(request.data) request.url = request.url + '?' + request.data } return request})// 响应拦截器Request.interceptors.response((response: any) => { const token = uni.getStorageSync('userData').token if (response.data.code === 102) { uni.showToast({ title: token ? '请重新登录' : '请先登录', icon: 'none', duration: 2000, }) uni.removeStorageSync('userData') // console.log(store) // store.dispatch(AppActionTypes.ACTION_LOGIN, {}) const url = '/pages/template/user/index' setTimeout( function() { uni.switchTab({ url }) }, 2000) } return response})// 设置默认配置Request.setConfig((config: any) => { config.header['device-os'] = platform // #ifdef APP-PLUS config.baseURL = HTTP_REQUEST_URL_APP // #endif // #ifndef APP-PLUS config.baseURL = HTTP_REQUEST_URL_H5 // #endif if (uni.getStorageSync('userData')) { config.header['token'] = uni.getStorageSync('userData').token // config.header['id'] = uni.getStorageSync('userData').id // config.header['uid'] = uni.getStorageSync('userData').userIdBuss // config.header['pid'] = uni.getStorageSync('userData').lmpt_userid } return config})export default Request
src下创建app文件,并完善工程文件
//在app文件下创建api文件夹 如:app/api/index.tsimport request from '@/utils/request' //导入request/** * API 数据总操作类 * Author Chenxiao * Time 2023-02-09 * 任何傻子都能写出电脑能识别的代码,但我能写出任何人都能看懂的代码 */const options = { header: { 'content-type': 'application/x-www-form-urlencoded'}, token: uni.getStorageSync('userData').token}/** * @method 不同请求通用写法接口 */export function testGet(data :any) { return request.get('', data)}export function testPost(data :any) { return request.post('', data, options)}export function testPut(data :any) { return request.post('', data)}export function testDelete(data :any) { return request.delete('', data)}/** * @method 正式接口 * */}export default API
下一节我们继续把剩余的几个配置做一个完善,例如,底部菜单数据载入,全局静态参数配置,文件自动混入等
欢迎大家收藏、点赞和转发,我们一起学习成长!
标签: #mysqluuiduuid