优雅,太优雅了(项目中代码质量和手撸业务)

代码质量

env配置文件

env文件后端需要进行相应的转换或者变动,以适应正式环境的部署

  1. url:有关跳转路径或者回调路径,都需要放入env中,因为开发环境和正式环境的路径可能不同,后端需要转成正式环境的路径

  2. 令牌和密钥:令牌和密钥是由后端生成的,保证请求是由正确的用户发送的,而不是其他无关用户。并且可能由于一些原因令牌和密钥发生了变化,后端可以直接修改。

  3. axios的baseUrl:在开发、测试和生产环境中,API 的基本路径可能会有所不同。

枚举和常量

枚举

当代码中存在常量列表:

js 复制代码
const obj = {google:100,Apple:102,Facebook:103,email:107}

可以放在constants文件中转化成枚举:(注意:枚举名称第一个字符要大写

js 复制代码
export enmu Obj {
    Google = 100,
    Apple = 102,
    Facebook = 103,
    Email = 107
}

另一个🌰子

可以替换成(可真是太优雅了)

js 复制代码
export enum AttachType {
  propertys = 1,
  weapons = 2,
}
export const AttachMentType = {
  [AttachType.propertys]: {
    key: AttachType.propertys,
    type: "道具",
    common: null,
    allList: null,
  },
  [AttachType.weapons]: {
    key: AttachType.weapons,
    type: "武器",
    common: null,
    allList: null,
  },
};
html 复制代码
<div class="select-item-tab">
    <a-menu-item v-for="item in AttachMentList" :key="`${item.key}`">
      {{ item.type }}
    </a-menu-item>
</div>

常量

如果有些常量使用较多 或者有意义的字符串或者数字 ,仍然抽离出来放入constants中(常量是全部大写)

js 复制代码
export const MESSAGE = "创作不易,点个👍呗"
export const SECONDS = 1;
export const MINUTES = 60;
export const HOURS = 3600;

函数的抽离

依稀记得有人说过函数中的代码超过多少多少行就需要抽离出一个函数,以保证代码的可读性
一些功能功能相同的代码也需要抽离出来,否则太抽象了

比如以下代码,关于find(map,reduce之类的同理)

可以抽离成下述代码

js 复制代码
const trackData = (key: string) => {
  return infoData.value.find((item: InfoItem) => item.key === key);
};

布尔值的返回

有些时候代码可能写的太快,返回的布尔值没经过思考,直到被提醒才发觉

比如以下代码(大意了,属实没注意到)

可以直接写出

js 复制代码
return isObjextInArray;

还有一些例子

js 复制代码
return a==b

样式的放置

样式不要写在style中,就算再少也不行,不要偷懒,这样做的目的是为了维护性和可读性(代码更优雅)

lodash中判断为空的内置函数

对于 null、undefined、空字符串、空数组以及空对象,函数都返回 true;而对于非空对象 { name: 'John' } 和非空数组 [1, 2, 3],函数返回 false。

例如

js 复制代码
// 判断是否处于搜索状态
if (itemName.value !== "") {
    isShow.value = true;
} else {
    isShow.value = false;
}

可以转换成

js 复制代码
import { isEmpty } from "lodash-es";
isShow.value = !isEmpty(itemName.value);

let / const的使用

let声明变量,const声明常量

但ref声明的值是个变量,虽然知道和理解,但用起来谁记得啊(reactive同理)

js 复制代码
const itemName = ref(1)

解构赋值

常用于解构网络请求的值(即拦截),和props里的值

和上述一样,知道理解,用起来忘记

js 复制代码
watch(
  () => props.ui.items,
  (newItems) => {
    const { common, items, weapons } = newItems.value;
    AttachMentList[AttachType.propertys].common = common;
    AttachMentList[AttachType.propertys].allList = items;
    AttachMentList[AttachType.weapons].allList = weapons;
  },
  { immediate: true }
);

手撸业务

1. ant-design-vue中input-number组件中@blur事件无法触发?只能手撸一个blur事件了

场景:对于后台管理的每条列表数据的某个数值进行修改,当失焦时会触发保存事件,而不是手动的保存,也就是进行产品优化。团队使用的组件库是ant-design-vue,但在input-number组件中添加@blur却发现该事件无法触发,只能根据鼠标点击的位置来判断是否需要失焦

html 复制代码
<template>
    <st v-for="item in datas">
       <template #count="{ row }">
          <template v-if="row.editing">
            <input-number ref="inputNumberRef" v-model="row.count"/>
            <SaveOutlined class="ml-sm" @click="save(row)" /> // 保存图标
          </template>
          <span v-else>
            {{ row.count }}
            <EditOutlined class="ml-sm" @click="edit(row)" /> // 编辑图标
          </span>
        </template>
    </st>
<template>
js 复制代码
 const inputNumberRef = ref(null);
  // 定义一个 ref 来保存当前编辑的行
 const editingRow:any = ref(null);
 
 const isInitialClick = ref(true);
js 复制代码
const handleClickOutside = (event: any) => {
     if (isInitialClick.value) {
       isInitialClick.value = false;
       return;
     }
     【1】if (inputNumberRef.value && !inputNumberRef.value.$el.contains(event.target)) {
       // 点击输入框之外的区域,触发失焦操作
       if (editingRow.value) {
         // console.log(editingRow.value); // 输出当前编辑的行
         save(editingRow.value);
         editingRow.editing = false;
       }
     }
};
onMounted(() => {
 // 在组件的生命周期内添加点击事件监听器
 document.addEventListener('click', handleClickOutside);
});

onBeforeUnmount(() => {
 // 在组件的生命周期内移除点击事件监听器
 document.removeEventListener('click', handleClickOutside);
});

【1】先判断能不能拿到输入框的实例,$el指的是input-number这个组件的dom元素,event.target是当你触发点击事件时点击的元素。

从而可以进行判断,当你点击页面中的某个dom元素时,就会触发handleClickOutside事件,如果你点击的dom元素不在input-number这个antd组件里,说明你点击了input-number之外的dom元素,则表明失焦了,触发相应事件;如果input-numbe组件dom元素包含你点击的dom元素,则没有失焦。

js 复制代码
   const save = (row: IItem) => {
     if (row.count <= 0 || !row.name) {
       message.warn("请完善附件");
       return;
     }
     row.id = items.value!.items.find((i) => i.value === row.id)!.value;
     row.editing = false;
     datas.value = [...datas.value];
     changeValue();
   };
js 复制代码
    const edit = (row: IItem) => {
      if (editingRow.value) {
        // 如果已经有正在编辑的行,将其设为非编辑状态
        editingRow.value.editing = false;
      }
      isInitialClick.value = true; // 重置为true,以防止编辑图标的第一次点击触发handleClickOutside
      row.editing = true;
      editingRow.value = row;
    };    

2. ant-design-vue中的级联展示无法自定义,只能结合下拉菜单手撸一个了

antd中的级联

手撸成图

输入框部分,用于存放选择后的值和点击显示弹窗

html 复制代码
// trigger触发下拉的行为,visible(v-model)控制弹窗是否显示,placement菜单弹出位置
<a-dropdown :trigger="['click']" v-model:visible="visible" placement="topLeft">
    <div @click="show">
      <DownOutlined />
      <div>
        <a-input
          v-model:value="itemName"
          @focus="show"
          @blur="hide"
        />
      </div>
      <span :class="{ editing-label: visible, hide-label: itemName }">{{ label }}</span>
    </div>
</a-dropdown>

大致逻辑:input被点击或者聚焦时弹框展示,失焦时弹窗关闭。并且当label有值且弹窗展示时,label值的颜色为灰色,而在输入框中输入了itemName值时,label的值不展示。

js 复制代码
const itemName = ref("");
const label = ref("");
// 弹窗默认关闭
const visible = ref(false);
// 弹窗关闭
const hide = () => {
  visible.value = false;
};
// 弹窗展示
const show = () => {
  visible.value = true;
};
css 复制代码
.editing-label {
  color: #bfbfbf;
}
.hide-label {
  opacity: 0;
}

弹窗部分

html 复制代码
 <template #overlay>
      <div>
        <a-menu
          // 选中时a-menu-item的高亮数组key值,默认选中道具
          v-model:selectedKeys="selectArray"
          @click="handleMenuClick"
          // 呈现左右弹性布局
          style="display:flex"
        >
          <div>
            <a-menu-item key="1"> 道具 </a-menu-item>
            <a-menu-item key="2"> 武器 </a-menu-item>
          </div>
          <div
            :class="{ tabhidden: true,tabshow: kCode == 1 }"
          >
              <div
                v-for="item in itemsList"
                @click="changeValue(item)"
              >
                <span>{{ item.label }}</span>
                <span>{{ item.value }}</span>
              </div>
          </div>
          <div :class="{ tabhidden: true,tabshow: kCode == 2 }">
              // 上同,除了v-for遍历的列表不同
          </div>
        </a-menu>
      </div>
    </template>

大致逻辑:主要是点击道具或者武器时,获取到它的key值,然后根据点击key值展示相应的数据

js 复制代码
// 级联高亮控制
const selectArray = ref(["1"]);

// 判断点击的是道具还是武器,然后展示相应的数据列表
const handleMenuClick = (event) => {
  kCode.value = event.key;
};

// 选择完后再次选择时,搜索栏为空,弹出默认为道具栏
const changeValue = (item) => {
  label.value = item.label;
  itemName.value = "";
  kCode.value = 1;
  selectArray.value = ["1"];
  hide();
};
css 复制代码
.tabhidden {
  display: none;
}
.tabshow {
  display: block;
  padding: 0;
  margin: 0;
  width: 380px;
  height: 290px;
}

3. 网络拦截

js 复制代码
getUser
    .then((resp) => {
        console.log(resp);
    })
    .catch((error) => {
        ElMessage.error(error);
    })

.then里的resp是拦截中resolve的值,比如resolve(data)

.catch里的error是reject里的值,比如reject(msg)

js 复制代码
const instance = Axios.create();

instance.interceptors.response.use(()=> {
    const { code = -1, data = {}, msg = "" } = response.data;
    if (handleUnlogin(code)) {
      return Promise.reject(msg);
    }
    if (code === HttpCode.SUSPENSION) {
      redirectSuspension();
      return Promise.reject(msg);
    }
    if (code === HttpCode.Ok) {
      return Promise.resolve(data);
    }
    return Promise.reject(msg);
})
相关推荐
工业互联网专业1 小时前
基于springboot+vue的医院门诊管理系统
java·vue.js·spring boot·毕业设计·源码·课程设计·医院门诊管理系统
九月TTS1 小时前
TTS-Web-Vue系列:Vue3实现内嵌iframe文档显示功能
前端·javascript·vue.js
我爱加班、、1 小时前
Chrome安装最新vue-devtool插件
javascript·vue.js·chrome·vue-devtool
澄江静如练_2 小时前
小程序 存存上下滑动的页面
前端·javascript·vue.js
源码方舟2 小时前
基于SpringBoot+Vue的房屋租赁管理系统源码包(完整版)开发实战
vue.js·spring boot·后端
m0_513962532 小时前
vue-ganttastic甘特图label标签横向滚动固定方法
javascript·vue.js·甘特图
菜鸟una2 小时前
【taro3 + vue3 + webpack4】在微信小程序中的请求封装及使用
前端·vue.js·微信小程序·小程序·typescript·taro
Java&Develop3 小时前
怎么查看当前vue项目,要求的node.js版本
vue.js
松树戈3 小时前
openfeign与dubbo调用下载excel实践
vue.js·spring cloud·elementui·dubbo
码农黛兮_463 小时前
HTML、CSS 和 JavaScript 基础知识点
javascript·css·html