likes
comments
collection
share

Vue3: 产品的花样-反向自动匹配国际区号

作者站长头像
站长
· 阅读数 16

简述

正常情况下,我们会像如图所示:

Vue3: 产品的花样-反向自动匹配国际区号 自个选择区号和手机号,然后如果区号和手机号匹配不上就直接表单报错,这是最简单的一种校验方式,但是呢,我们的产品就是比较喜欢折腾前端,啊,说错了。应该说,我们的产品比较亲和用户,站在用户的角度去思考,提高体验感,所以就有了下面这一波设想(我们前端称之为----需求) 先看图:

Vue3: 产品的花样-反向自动匹配国际区号

需求如下:

  1. 必填

  2. 输入框提示文案:请输入手机号

  3. 合法性:手机号格式,根据不同区号,有相应的格式验证

  4. 交互:

    • 获得焦点时,弹出数字键盘,输入内容后,显示一键清空的按钮
    • 用户填写后需根据用户填写的手机号,点击“获取验证码”或“登录”,反向匹配国际区号,若当前国际区号匹配则无需变动,若不匹配则提示用户(弹窗如图),用户点击“确定变更”则关闭弹窗且自动变更为匹配的国际区号,若点击“取消”则直接关闭弹窗,不变更国际区号

    已有规则可以做反向匹配的:

    • 手机号为大陆号码格式(11位),则区号纠正为:+86;
    • 香港号码格式(5、7、8、9开头的8位)纠正为:+852;
    • 澳门号码格式(6开头的8位),纠正为:+853
  5. 用户切换登录方式,需自动记忆切换之前的值

实现

第一步:正则表达式

根据产品给出的规则

  • 手机号为大陆号码格式(11位),则区号纠正为:+86;
  • 香港号码格式(5、7、8、9开头的8位)纠正为:+852;
  • 澳门号码格式(6开头的8位),纠正为:+853

可以写出相应的校验表达式:

// 中国大陆手机号码格式(11位),区号纠正为+86
function correctMainlandPhoneNumber(phoneNumber) {
  const pattern = /^1\d{10}$/;
  if (pattern.test(phoneNumber)) {
    return "+86" + phoneNumber;
  }
  return phoneNumber;
}

// 香港手机号码格式(8位,开头为5、7、8、9),区号纠正为+852
function correctHongKongPhoneNumber(phoneNumber) {
  const pattern = /^[5|7|8|9]\d{7}$/;
  if (pattern.test(phoneNumber)) {
    return "+852" + phoneNumber;
  }
  return phoneNumber;
}

// 澳门手机号码格式(8位,开头为6),区号纠正为+853
function correctMacauPhoneNumber(phoneNumber) {
  const pattern = /^6\d{7}$/;
  if (pattern.test(phoneNumber)) {
    return "+853" + phoneNumber;
  }
  return phoneNumber;
}

// 测试示例
const mainlandNumber = "13812345678";
const hongKongNumber = "91234567";
const macauNumber = "61234567";

console.log(correctMainlandPhoneNumber(mainlandNumber)); // Output: +8613812345678
console.log(correctHongKongPhoneNumber(hongKongNumber)); // Output: +85291234567
console.log(correctMacauPhoneNumber(macauNumber)); // Output: +85361234567

也就是:

  • +852对应/^([5|7|8|9])\d{7}$/
  • +853对应/^[6]\d{7}$/
  • +86对应/^1\d{10}$/

但这里要注意一下:我们的产品并没有详细叙说中国大陆的校验规则,查了文档才知道:

中国大陆的手机号码校验规则如下:

  1. 号码长度为11位数字。
  2. 第1位为1,表示移动通信。
  3. 第2位为3、4、5、7、8、9中的一位,表示运营商的归属地区。

运营商归属地区对应如下:

  • 3开头:中国电信
  • 4开头:中国移动
  • 5开头:中国电信
  • 7开头:中国移动
  • 8开头:中国联通
  • 9开头:中国联通

根据以上规则,可以使用以下正则表达式进行中国大陆手机号码的校验:

/^[1][3-9]\d{9}$/

得到了正则表达式,我们就可以进行第二步骤了

第二步:方法封装

template部分:

<template>
	<t-dialog
		v-model:visible="visible1"
		theme="info"
		header="提示"
		:body="textInfo"
		:close-btn="false"
		:on-close="closeDialog"
		class="login-out-btn"
		:confirm-btn="$t('lss.sure_switch')"
		:cancel-btn="$t('order.cancel')"
		z-index="2501"
		@confirm="onClickConfirm"
	>
	</t-dialog>
</template>

script部分:

// 自动校验手机匹配
const onBlurPhone = (e) => {
	console.log(e);
	if (!e) return;
	const code = checkCodeByPhone(e);
	if (code && formData.value.telCode != code) {
		// formData.value.telCode = code;
		codeV.value = code;
		textInfo.value =
			proxy.$i18n.locale === 'zh-CN'
				? `检测到你输入的手机号对应的国际区号为"+${code}",是否为你自动变更区号`
				: `檢測到你輸入的手機號對應的國際區號為"+${code}",是否為你自動變更區號`;

		visible1.value = true;
	} else {
		// MessagePlugin.error('手机号格式错误,请重新输入');
		// setTimeout(() => {
		// 	formData.value.telephone = undefined;
		// });
	}
};

解读:

这段代码是用于自动校验手机匹配的。首先,我定义了一个名为onBlurPhone的函数,该函数接收一个事件参数e。在函数体内部,打印出事件参数e。

接下来,使用checkCodeByPhone函数来检查手机号对应的区号。如果区号存在且与formData对象中的telCode属性不匹配,那么会将区号赋值给codeV,并根据当前语言环境显示一条提示信息,询问用户是否自动变更区号。 随后,将visible1属性设置为true,用于显示某个界面元素。 如图:

Vue3: 产品的花样-反向自动匹配国际区号

如果手机号对应的区号不存在或者与telCode属性匹配,那么代码中暂时没有其他处理逻辑,可以根据实际情况自行添加。

大概的实现步骤就如上面所说的了;对了,选择区号这个组件是自个封装的,有需要代码的可以评论留名哈哈哈!

Vue3: 产品的花样-反向自动匹配国际区号

总结

在实现选择国际区号的弹层交互时,你可以按照以下步骤进行:

  1. 创建一个按钮或输入框,用于触发选择国际区号弹层的显示;
  2. 定义一个存储选择的国际区号的变量,以及一个控制弹层显示/隐藏的变量;
  3. 创建一个方法来控制弹层的显示和隐藏;
  4. 在弹层中展示国际区号列表,并通过循环渲染进行展示;
  5. 创建一个方法用于选择国际区号,并在选择完成后更新存储选择的变量的值;
  6. 根据需求,定制弹层的样式,包括弹出位置、背景色、边框样式等。

我这个小总结提供了一个简单的选择国际区号弹层交互的实现方案,你可以根据实际需求进行定制和扩展。通过封装和优化样式,可以提升用户体验并增加交互的友好性。

扩展--根据ip识别区号

后面产品附加了一个需求: 要根据地区IP自动识别默认手机区号 要通过获取网络IP识别并匹配当前区号,在Vue 3中实现,可以按照以下步骤进行操作:

  1. 使用axiosfetch等库来获取客户端的公网IP地址。请注意,为了获取客户端的真实IP地址,您需要在前端发送一个请求到一个支持返回真实IP地址的服务器。以下是一个使用axios获取IP地址的示例代码:
import axios from 'axios';

const getIPAddress = async () => {
  try {
    const response = await axios.get('https://api.ipify.org?format=json');
    return response.data.ip;
  } catch (error) {
    console.error(error);
    return ''; // 处理错误情况
  }
};

export default {
  data() {
    return {
      ipAddress: '',
      areaCode: ''
    };
  },
  mounted() {
    this.getIPAndAreaCode();
  },
  methods: {
    async getIPAndAreaCode() {
      const ipAddress = await getIPAddress();
      this.ipAddress = ipAddress;
      
      // 根据IP地址发送请求到您的服务器,实现IP地址到区号的映射
      // 接下来的步骤将会调用您的服务器API并将匹配到的区号保存在'areaCode'变量中
    }
  }
};

  1. 在服务器上设置一个API来处理前端发送的IP地址,并将其与区号进行匹配。您可以使用Node.js、Express或其他后端技术来实现。以下是一个简单的示例:
const express = require('express');
const app = express();

// 根据IP地址匹配区号的路由处理程序
app.get('/api/areaCode/:ip', (req, res) => {
  const ip = req.params.ip;
  
  // 这里可以使用IP地址库或其他方法来进行IP地址到区号的映射
  // 示例中直接使用一个硬编码的映射
  const areaCodeMap = {
    '192.168.0.1': 'XXX',
    '192.168.0.2': 'YYY',
    // 更多IP地址和对应的区号...
  };
  
  const areaCode = areaCodeMap[ip] || 'N/A'; // 没有找到匹配的区号时,默认为 'N/A'
  
  res.json({ areaCode });
});

// 启动服务器
app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

  1. 在Vue组件中调用服务器API来匹配区号:
<template>
  <div>
    <p>IP Address: {{ ipAddress }}</p>
    <p>Area Code: {{ areaCode }}</p>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      ipAddress: '',
      areaCode: ''
    };
  },
  mounted() {
    this.getIPAndAreaCode();
  },
  methods: {
    async getIPAndAreaCode() {
      try {
        const response = await axios.get('http://your-server-ip:3000/api/areaCode/' + this.ipAddress);
        this.areaCode = response.data.areaCode;
      } catch (error) {
        console.error(error);
        this.areaCode = 'N/A'; // 处理错误情况
      }
    }
  }
};
</script>

在该代码中,getIPAndAreaCode方法发送一个GET请求到服务器API来匹配IP地址与区号。请确保将http://your-server-ip替换为我们实际的服务器IP地址或域名。

转载自:https://juejin.cn/post/7276364913424728121
评论
请登录