Vue 基础代码片段(业务向)

203 阅读3分钟

笔者一年前做B端项目的时候,用的是Vue框架,开发中发现很多场景的相似性,且Vue语法相对React而言不够简洁,因此提炼出了共性的、高复用的代码片段(仅适用于新手水平),虽然当时只是经验不足的小小实习生一枚,且此后主要做React开发,但总结的这些片段依旧具有一定的意义,故整理出来:

表单验证

formRef.value
    .validateFields() // 验证表单中所有字段的值是否符合预期的规则
    .then()
    .catch(() => {
      btnLoading.value = false; // 取消按钮的Loading状态
      emits("search", formState.value); // 将表单的值传递给父组件
    });

父子组件传值

// 子组件
const props = defineProps({
  options: {
    type: Array,
    required: true,
  },
  formData: {
    type: Object,
    default: () => ({}),
  },
});
// 父组件

对表格数据作特殊展示

例如对身份证号进行加密展示,只需要定义一个字符串的替换规则(replace()+正则匹配)

将原本的数据替换之后使用{{}}动态展示

<template #bodyCell="{ column, record }">
        <template v-if="column.dataIndex === 'idCard'">
          {{ maskedId(record.idCard) }} 
        </template>
</template>

const maskedId = (idCard: number | string) => {
  return idCard
    .toString()
    .replace(
      /(?<=\d{3})\d{12}(?=\d{2})|(?<=\d{3})\d{15}(?=\d{3})/,
      "************"
    );
};

又例如对所选择的日期进行Date类型格式转换,

需要将收到的字符串形式通过 new Date(Date.parse(start))转换 —— 日期格式;

如果是时间戳(一串数字)就只需要Date.parse方法;

<a-form-item label="活动时间">
        <a-range-picker
          v-model:value="activityDuration"
          show-time
          format="YYYY-MM-DD HH:mm:ss"
          value-format="YYYY-MM-DD HH:mm:ss"
          @change="handleRangeChange"
        ></a-range-picker>
</a-form-item>

const handleRangeChange = function (value: string[]) {
  if (value) {
    const [start, end] = value;
    formState.value.activityStart = new Date(Date.parse(start));
    formState.value.activityEnd = new Date(Date.parse(end));
  }else {
    formState.value.activityStart = null;
    formState.value.activityEnd = null;
  }
};

限制用户输入类型

可以使用onkeyup事件去替换replace所输入的字符串;然后在提交时再转换为数字;

      <a-form-item label="活动编号">
        <a-input
          v-model:value="formState.activityId"
          placeholder="请输入活动编号"
          onkeyup="value=value.replace(/[^0-9]/g, '')"
        ></a-input>
      </a-form-item>

优雅的请求处理

项目一般都会拦截请求失败的情况并进行统一处理,因此在调用接口时可以只处理请求成功的逻辑;

  await listOrder({
    pageIndex: 1,
    pageSize: 4,
    traceId: uniqueId,
    platform: 1,
    ...params,
  }).then(({ data }) => {
    console.log("sellerOrderList", data.sellerOrderList);
    tableData.value = data.sellerOrderList;
    total.value = data.total;
  });
// 或者
  await listExchangeRules(params).then(({data})=>{
    if (data.totalElements) {
      formData.value = data.content
      total.value = data.totalElements;
      console.log("loadTable", "total", total.value);
    } else {
      formData.value = null;
      total.value = 0;
    }
  })

三级类目懒加载

const loadData = async (selectedOptions: any) => {
  const targetOption = selectedOptions[selectedOptions.length - 1];
  targetOption.loading = true;
  console.log(targetOption.value);
  await querySubCategory({ parentId: targetOption.value }).then(({ data }) => {
    targetOption.loading = false;
    // 方案一:根据返回的data判断是否显示展开符
    // if (data.length == 0) {
    //   targetOption.isLeaf = true;
    //   console.log(targetOption);
    // }
    targetOption.children = data.map((item: any) => {
      const { categoryId, categoryName } = item;
      console.log(data.length, data.length == 0);
      // 方案二:当目前是两级类目,第三级目录则不显示展开符
      return selectedOptions.length == 2
        ? {
            value: categoryId,
            label: categoryName,
            children: [],
          }
        : {
            value: categoryId,
            label: categoryName,
            children: [],
            // 目前为一级类目时,默认显示展开符
            isLeaf: false,
          };
    });
  });
};

子组件分页功能

const total = toRef(props, "total");
const pagination = ref({
  current: 1,
  defaultPageSize: 20,
  total: 0,
  showTotal: () => `共 ${total.value} 条`,
  onChange: (current: number, size: number) => {
    pagination.value.current = current;
    pagination.value.defaultPageSize = size;
    // 把新的页码发给父组件调用接口请求
    emits("pageChange", pagination.value.current);
  },
});

// 必须watch总数total的变化,否则total永远是0
watch(total, (newValue: number) => {
  pagination.value.total = newValue;
  // 父组件loadTable后,子组件可以监听到数据变化,此时把当前页码设置为1
  pagination.value.current = 1;
  console.log("watch-total", total.value, "cur", pagination.value.current);
});

本文的分享就到这里,谢谢观看~