封装类

# 封装类

# axios封装
  • 导入axios函数

    import axios,{AxiosResponse // 请求返回值类型
                  ,AxiosPromise
                  ,AxiosInstance //axios实例类型
                  ,AxiosRequestConfig, //请求配置参数类型
                  AxiosRequestHeaders, // 请求头参数
                 } from 'axios'
    
    
  • 创建axios实例

    const axiosInstance:AxiosInstance = axios.create({
        baseURL:"" // 默认地址
        timeout:3000  // 超时默认值
    })
    
    // 
    请求拦截器
    axiosInstace.interceptors.request.use((config:AxiosRequestConfig)=>{
        const userId ='1' // 获取用户id,并携带
        const headers:AxiosRequestHeaders={
            userId
        }
        headers['distributorId'] = '1'
        return ...config,headers
    })
    //请求拦截器
    axiosInstace.interceptors.response.use((response:AxiosResponse)=>{   // 请求成功走这里
        const powerStore = useStore().power 
        if(data.code == '0')      //当为0的时候代表正确
            powerStore.changePower(true) //存储到vuex中
        return data
        )
        if(data.code == 'distribution.memberNotInDistributor'{
            reoter.push({name:"nolog"}) // 没有权限
            return Promise.reject( response) // 返回一个错误
            // 没有权限
        }
        if(data.code === 'distribution.member_not_permission'{
    	   return Promise.reject(data)
        }
        // 无效的UAT
        if(data.code == 'idServer.1020'){
    	 	 return Promise.reject(data)
        }
        //返回错误信息
        const errMessage = data.message
        message.error(errMessage)
        retrun Promise.reject(response)
    },(err)=>{                                                  // 请求失败走这里
        if(error.response){
            const { data,status } = error.response
            const message = !data ? '网络连接异常,请稍后再试'showMessage(status)
            if(status===401){
                window.location.href ='地址’  //不知道什么地址
                return
             }
            router.push({name:”error‘,params:{status,message}})
            return Promise.reject(data)
            
        }
    }}
    }//导出  封装工具
    export default function request<T>(url='',params={},type='Post',query?:{}):Promise<requestReturnType<T>{
        let promise:AxiosPromise
        return new Promise<requestReturnType<T>>(resolve,reject)=>{   //返回一个promise对象
    		if(type.toUpperCase == 'GET'){
          		promise = axiosInstance({
           		method: 'GET',
            	url,
                params
          		})
       		 } else if (type.toUpperCase() === 'POST') {
        		promise = axiosInstance({
            	method: 'POST',
            	url,
            	data: params,
            	params: query
          	})
        	} else if (type.toUpperCase() === 'DELETE') {
          		promise = axiosInstance.delete(url, params)
        	} else if (type.toUpperCase() === 'PUT') {
          		promise = axiosInstance.put(url, params)
       		 } else {
          		promise = axiosInstance({})
        	 }
            promise.then((res)=>{
                resolve(res as unknown as requestReturnType<T>)
            }.catch((error)=>{reject(error)})
            }
    		}
        }
        
        
    }
                                           
    
    # svg封装
    <template>
     <svg 
    aria-hidden="true"   //aria-hidden 为了避免现在的辅助技术能够识别并朗读 
    :style="{width:size+`${rem ? 'rem':'px'}`}"
    <use :href='symboid' :fill="color">
    </svg>
    </template>
    <script lang="ts">
        export default defineComponent({
    	name:"SvgIcon",
            props:{
                profix:{
                    type:String,
                    default:'icon',        
                },
                name:{
                	type:String,
                    required:true,
                },
               color:{
               		typr:sTRING         
                },
                size:{
    				type:Nuber,
                    default:'36'
                rem:{
                    type:Boolean,
                    default:"10"
                    }
                }
                    
         setup(props){
    			const symboiId=computed(()=>`#${props.prefix}-${props.name}`return { symbolIds}
         }
            }
                    
    })
    
    # 按钮封装
    <template>
        <a-button v-bind='attrs' :disable="disable">
            <tempalte v-if="props.hsaIcop">
                <a-space align="center" :size="4">
                    {{props.text}}
                    <span class="app-button-icon-wrap">
                        <SvgIcon :name="props.iconDir!" style="font-size:16px"></SvgIcon>
    				</span>
    			<a-space>
             </template>
    		<template v-else>
            	{{props.text}}
            </template>
    </template>
    <script setup lang="ts">
        const attrs=useAttrs()   //穿透,继承父元素的类和属性
       const props = withDefaults(     withDefaults // 是给defineProps 绑定默认值
       defineProps<{ text:string, iconDir?:string, hasIcon?:boolean, disabled?:boolean}>(){
           iconDir:"",
           hasIcon:false
       }</script>
    
    # 封装弹除层
    <template>
    <a-modal :mask-closable = 'false' v-bind="attrs" warpClassName="app-confirm-modal-warp" :okButtonProps="okBittonProps" centered>   
        <template #title>
        		<span>
                    <i>
              <SvgIcon v-if="props.type === 'DISABLE'" name="components-warning</SvgIcon>
             <SvgIcon v-if="props.type === 'DISABLE'" name="components-warning"></SvgIcon>
             <SvgIcon v-if="props.type === 'DISABLE'" name="components-warning"></SvgIcon>
                    </i>
    		{{props.titleText}}
    	<template #footer v-if="hide">
        	<a-button @click="handleCancel" type="primary">我知道了</a-button>
        </template>
    </tempalte>
    <script>
             const props = defineProps<{titleText:string type:"ENABLE" | "DIS" | 'PRO' 
                                      	hide?:boolean}>()
    		const attrs = useAttrs()
            const okButtonProps = computed(()=>(props.type === 'DISABLE' ? {danger:true}:{}))
            const emit = defineEmits(['handleCancel'])
            const handleCancel = () =>{
    		emit('handleCancel')
            }
    </script>
    
    mask-closable // 点击遮罩层不关闭
    attrs //穿透。
    warpClassName //对话框外层容器的类名
    okButtonProps //ok按钮Props
    centered   //中心位置
    
    # 封装筛选按钮
    <template>
    	<div>
            <a-form ref="formRef" name='table_advanced_search' :model=formState>
        		<a-row :gutter="24">
                    <tempalte v-if="useFlex">
        					<template v-for="item in filterOptions" :key="item.field">
                                <a-col :flex="item.flex">
        						<a-form-item v-if="formState[`${item.field}`] !== 										undefined" :name="`${ item.field}`" 											:label="`${irem,type !=='INPUT-GRPOUP' ? item,label :''}`"
                                                 :required = "item.required">
                                    <tempalate v-if=”item.type === 'STRING'“>
        						<a-input v-model:vlaue="formState[`${item.fiweld}`] 									:palceholder ="item.placeholder">
        						</a-input>
        							</tempalate>
                                                                                                                           <template v-if="item.type === 'SELECT'">
        								<a-select
        								v-model:value="formState[`${item.field}`]"
                                        @change="onChange($event,item.field)"
                                         :mode="item.options?.multiple ?                                                        'multiple':undefuned"
        								>
        								
        								</a-select>
        							</tempalte>
    								    	
                   
        							</a-form-item>
        						</a-col>
        			</tempalte>
                    
        		</a-row>	
       		 </a-form>
        </div>
    </template>
    
# 取别名@
先在vite.config.js中配置

 resolve: {
      alias: [
        {
          find: '@',
          replacement: pathResolve('src') + '/'
        },
        {
          find: 'components',
          replacement: pathResolve('src/components') + '/'
        },
        {
          find: 'utils',
          replacement: pathResolve('src/utils') + '/'
        },
        {
          find: 'store',
          replacement: pathResolve('src/store') + '/'
        },
        {
          find: /\/types\//,
          replacement: pathResolve('types') + '/'
        }
      ]
    },
        
        
 如何配置了ts 需要在tsconfig.json中配置
"baseUrl": "./",
    "paths": {
      "@/*":  ["src/*"],
      "components/*":  ["src/components/*"],
      "utils/*":  ["src/utils/*"],
      "store/*":  ["src/store/*"],
      "/types/*":  ["types/*"],
    }
# 自动导入vue3的API
下载
npm i -D unplugin-auto-import
在vite-config中使用
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";
// import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'

// https://vitejs.dev/config/

在plugins中中使用

 plugins: [
    vue(),
    AutoImport({
      include: [
        /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
        /\.vue$/,
        /\.vue\?vue/, // .vue
      ],
      imports: ["vue", "vue-router", "pinia"],
      eslintrc: {
        enabled: false,
        filepath: "./.eslintrc-auto-import.json",
        globalsPropValue: true,
      },
      dirs: ["./src/store"],
      vueTemplate: true,
      dts: "src/types/auto-import.d.ts",
    }),
    Components({
      resolvers: [AntDesignVueResolver({ importStyle: false })],
      dts: "src/types/components.d.ts",
    }),
    // 自动导入图标
    // createSvgIconsPlugin({
    //   iconDirs: [resolve(process.cwd(), "src/assets/icons")],
    //   symbolId: "icon-[dir]-[name]",
    // }),
  ],
     
 ts文件需要创建一个/auto-import.d.ts
这可能自动导入,看项目

如何在vite中使用到响应式布局

使用到插件
在vite中使用postcss和autoprefixer
npm i postcss autoprefixer postcss-pxtorem -D


----
在vite.config.js 配置
// 自动根据px转换成rem
 css: {
    postcss: {
      plugins: [
        autoprefixer({
          overrideBrowserslist: ["Android>=4.0", "iOS>=7"],  //大于android或ios
        }),
        pxtorem({
          rootValue: 16,     
          propList: ["*"],
          selectorBlackList: [":root"],
        }),
      ],
    },
  },
  ---
      自动配置根节点的fontsize
     
     创建一个工具函数
     const basesize =14
     
     function setSize(){
		let scale=1
        if(document.documentElement.clientWidth < 1325 ){
				sclae= document.documentElement.clientWidth / 1325
            if(document.docuemntElement.clientWidth<1097){
			scale = 1097 / 1325	
            }
       	 }
         document.documentElement.style.fontSize= baseSize *Math.min(scale,1)+'px'
     }
     setRem()
     window.onresize = useDebounceFn(()=>{
			setRem()
     },150)
     export{}

--在全局使用type类型

在src目录下新建一个types目录
types新建home.d.ts文件
--homde.d.ts-- // 
export interface IPreps{
		value:'1',
		lable:'1
}
--index.ts ---
export * from './home'     // 导出所有类中home的
--调用---
import type { IProps } from ‘@。。/。/。’
---defineProps---
deineProps<Iprops>()

定义搜索框组件

KeyboardEvent:是ts内置的鼠标键盘事件
函数定义接口
interface IEmits interface IEmits {
  (e: "search", v?: string | number): void;  //e是事件,v是参数,void是返回值
  (e: "cancel"): void;
  (e: "clear"): void;
  (e: "update:modelValue", v?: string | number): void;
}


emit使用update

父组件
由于vue3废弃掉了.sync,所有在调用时需要通过 v-model:drawerShow绑定
子组件
const emit = defineEmits(['update:drawerShow'])

如何触发点击事件e

获取目标元素的类
e.target.classList
判断该类中是否包含这个类名
e.target.classList.contains(')
    思念是一种病
    蔡健雅/张震岳