vue3项目踩坑

判断当前环境

在vue3中使用process 来判断当前环境时会报错,在获取环境时应该用import.meta.env.MODE来获取当前的环境数据

实现点击全屏

使用可以使用screenfull插件实现全屏的效果

  1. npm install screenfull
  2. 引入screenfull,注册事件
    import screenfull from "screenfull";
    // 当前是否全屏
    const isScreenfull = ref(false);
    // 全屏/非全屏切换
    const changeIsScreenfull = () => {
     	isScreenfull.value = screenfull.isFullscreen;
    };
    
  3. 注册事件
    <div class="screenfull" @click="onToggle"> 
    	<el-icon>
      		<FullScreen />
    	</el-icon>
    </div>
    // 监听屏幕改变
    onMounted(() => {
    	screenfull.on("change", changeIsScreenfull);
    });
    // 移除监听
    onUnmounted(() => {
    	screenfull.off("change", changeIsScreenfull);
    });
    // 切换事件 
    const onToggle = () => {
     	screenfull.toggle();
    };
    

reactive相关问题

  1. reactive定义的对象不能通过重新赋值来实现响应式的改变,因为使用proxy代理的是对象的地址,在重新赋值后,对象的地址发生了改变,代理响应式也就失效了。如:修改数组中的元素:
    let list = reactive([1,2,3,4,5])
    //方法1 这样更改不会触发界面刷新
    list = list.filter(item=>item >= 3)
    
    // 方法2,使用数组的方法改变原数组可以获得vue的响应式操作
    const index = list.find(item=>item)
    for (let i = 0; i < list.length; i++) {
     if (list[i] > 3) {
     	 list.splice(i, 1);
    	  i--;
     	}
     }
    // 对于对象,可以使用Object.assign赋值、新增等操作
    const obj = reactive({})
    obj.a = 12
    Object.assign(obj,{ a:999, b:'张三 }) // 会触发视图的更新
    

vue实现页面局部刷新的方法

原理:使用v-if绑定的路由,当v-if的数据发生变化时,vue会重新渲染对应的路由

  1. 给需要进行局部刷新的路由加上v-if
    const isReload = ref(true)
    <router-view v-if="isReload"></router-view>
    
  2. 定义刷新函数,并将其注入到后代组件中
    const reload = () => {
    	isReload.value = false;
    	nextTick(() => {
    		isReload.value = true;
    	});
    };
    provide("reload", reload);
    
  3. 在后代组件中接受reload函数,通过调用该函数实现界面的局部刷新
    interface funType {
    	(): void;
    }
    const reload = inject("reload") as funType;
    <el-button @click='reload'>局部刷新</el-button>
    

原生API

contains:判断元素是否为某一元素的后代节点

类型注解相关问题

axios

在使用axios的过程中,会发现他的返回值类型始终是AxiosPromise<any>,这就导致了我们在获取接口数据的时候失去了ts带来的提示功能。

问题描述:

我在axios的响应拦截器里将返回的data数据统一拆分出来返回,而ts不会管这个地方,而是直接判断我们封装后的axios的返回值,在后续的类型判断中,无论怎么设置类型,都会提示:不能将类型XXX赋值给AxiosPromise<any>

interface information<T = any> = {
  code: 1000 | 2000;
  message: string;
  data?: T;
};
interface salaryDataType {
  date: String;
  baseWage: Number;
  salary: Number;
  id: string;
  remark?: string;
}
// 提示:“AxiosPromise<any>”缺少类型“information<salaryDataType[]>”中的以下属性: code, message
export const getSalaryData = (): information<salaryDataType[]> =>
 request({
   method: "post",
   url: "/salary",
  });
解决方法:

在响应拦截器中不对数据进行处理,而是在最终返回数据时对最终返回的数据进行处理。

export default async function (config: axiosConfig) {
  // 根据环境配置获取当前接口
  const baseURL = import.meta.env.VITE_BASE_URL;
  const instance = axios.create({ baseURL, timeout: 5000 });

  // 请求拦截器
  instance.interceptors.request.use((config) => {
    nprogress.start();
    return config;
  });

  // 响应拦截器
  instance.interceptors.response.use(
    (response) => {
      nprogress.done();
      const data: information<any> = response.data;
      if (data.code !== 2000) {
        ElMessage({
          type: "error",
          message: data.message,
        });
      }
      return response;
    },
    (error) => {
      const msg = error.message || undefined;
      nprogress.done();
      ElMessage({
        message: msg,
        type: "error",
        duration: 3000,
      });
      return Promise.reject(error);
    }
  );
  const res = await instance.request(config);
  return res.data;
}

这样处理后,返回值的类型就变成了Promise<any>,就可以为其赋上自己想要的类型啦。

export const getSalaryData = (): Promise<information<salaryDataType[]>>=>
  request({
    method: "post",
    url: "/salary",
  });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值