Vue 父页面调用子页面的方法,排序 sort localeCompare

Vue 父页面调用子页面的方法

父页面

 <el-col :lg="4" :xs="24" class="mb-[12px]">
        <HospitalTree
          ref="hospitalTreeRef"
          v-model="queryParams.HospitalId__eq"
          @node-click="handleQuery"
        />
      </el-col>

<script setup lang="ts">

const hospitalTreeRef = ref(); // 引用 HospitalTree 组件


// 查询
function handleQuery() {
  loading.value = true;
  hospitalTreeRef.value.handleQuery();
  HospitalAPI.getDeptList(queryParams)
    .then((data) => {
      pageData.value = data;
      total.value = data.Page.TotalCount;
    })
    .finally(() => {
      loading.value = false;
    });
}

// 重置查询
function handleResetQuery() {
  queryFormRef.value.resetFields();
  queryParams.PageNum = 1;
  queryParams.Status__eq = 1;
  queryParams.HospitalId__eq = null;
  // 清除树组件的选中状态
  if (hospitalTreeRef.value) {
    hospitalTreeRef.value.clearSelection();
  }
  handleQuery();
}

</script>

子页面

<script setup lang="ts">
// 暴露清除选中状态的方法
defineExpose({
  clearSelection,
  handleQuery,
});

/** 清除选中状态 */
function clearSelection() {
  if (hospitalTreeRef.value) {
    hospitalTreeRef.value.setCurrentKey(null);
    hospitalId.value = undefined;
  }
}

function handleQuery() {
  HospitalAPI.getHospitalList().then((data) => {
    hospitalList.value = data?.sort((a, b) =>
      a.HospitalName?.localeCompare(b.HospitalName)
    );
  });
}

onBeforeMount(() => {
  handleQuery();
});
</script>

排序

数据排序

//如果首字母是英文,这时候就会排到后面,
data?.sort((a, b) => a.HospitalName?.localeCompare(b.HospitalName)

首字母英文排前面

HospitalAPI.getHospitalList(param).then((data) => {
  hospitalList.value = data.BussinessData?.sort((a, b) => {
    const nameA = a.HospitalName || '';
    const nameB = b.HospitalName || '';
    
    // 判断是否为英文字母开头
    const isEnglishA = /^[a-zA-Z]/.test(nameA);
    const isEnglishB = /^[a-zA-Z]/.test(nameB);
    
    if (isEnglishA && !isEnglishB) {
      return -1; // a 是英文,b 是中文,a 排在前面
    } else if (!isEnglishA && isEnglishB) {
      return 1; // a 是中文,b 是英文,b 排在前面
    } else {
      // 都是英文或都是中文,按正常顺序排序
      const collator = new Intl.Collator('zh-CN');
      return collator.compare(nameA, nameB);
    }
  });
});

要让英文排在汉字前面,只需要调整一下排序逻辑。以下是几种实现方法:

方案1:使用 Intl.Collator(推荐)

HospitalAPI.getHospitalList(param).then((data) => {
  hospitalList.value = data.BussinessData?.sort((a, b) => {
    const nameA = a.HospitalName || '';
    const nameB = b.HospitalName || '';
    
    // 判断是否为英文字母开头
    const isEnglishA = /^[a-zA-Z]/.test(nameA);
    const isEnglishB = /^[a-zA-Z]/.test(nameB);
    
    if (isEnglishA && !isEnglishB) {
      return -1; // a 是英文,b 是中文,a 排在前面
    } else if (!isEnglishA && isEnglishB) {
      return 1; // a 是中文,b 是英文,b 排在前面
    } else {
      // 都是英文或都是中文,按正常顺序排序
      const collator = new Intl.Collator('zh-CN');
      return collator.compare(nameA, nameB);
    }
  });
});

方案2:使用 localeCompare 的简化版本

HospitalAPI.getHospitalList(param).then((data) => {
  hospitalList.value = data.BussinessData?.sort((a, b) => {
    const nameA = a.HospitalName || '';
    const nameB = b.HospitalName || '';
    
    // 判断是否为英文字母开头
    const isEnglishA = /^[A-Za-z]/.test(nameA);
    const isEnglishB = /^[A-Za-z]/.test(nameB);
    
    // 英文排在中文前面
    if (isEnglishA && !isEnglishB) return -1;
    if (!isEnglishA && isEnglishB) return 1;
    
    // 同组内正常排序
    return nameA.localeCompare(nameB, 'zh-CN');
  });
});

方案3:更简洁的写法

HospitalAPI.getHospitalList(param).then((data) => {
  hospitalList.value = data.BussinessData?.sort((a, b) => {
    const nameA = a.HospitalName || '';
    const nameB = b.HospitalName || '';
    
    // 英文排在前面,中文排在后面
    const typeA = /^[A-Za-z]/.test(nameA) ? 0 : 1; // 英文为0,中文为1
    const typeB = /^[A-Za-z]/.test(nameB) ? 0 : 1;
    
    // 先按类型排序(英文在前),再按名称排序
    return typeA - typeB || nameA.localeCompare(nameB, 'zh-CN');
  });
});

方案4:支持数字开头的完整版本

HospitalAPI.getHospitalList(param).then((data) => {
  hospitalList.value = data.BussinessData?.sort((a, b) => {
    const nameA = a.HospitalName || '';
    const nameB = b.HospitalName || '';
    
    // 定义优先级:数字 > 英文 > 中文
    const getPriority = (str) => {
      if (/^[0-9]/.test(str)) return 0; // 数字开头最高优先级
      if (/^[A-Za-z]/.test(str)) return 1; // 英文开头中等优先级
      return 2; // 其他(主要是中文)最低优先级
    };
    
    const priorityA = getPriority(nameA);
    const priorityB = getPriority(nameB);
    
    // 先按优先级排序,再按名称排序
    return priorityA - priorityB || nameA.localeCompare(nameB, 'zh-CN');
  });
});

推荐使用方案3,代码简洁明了,逻辑清晰:

  • 英文开头的医院名称排在前面
  • 中文开头的医院名称排在后面
  • 同类型的按中文拼音顺序排序

这样就能实现英文排在汉字前面的效果了。

posted @ 2025-09-10 10:29  VipSoft  阅读(15)  评论(0)    收藏  举报