当前位置: 首页 > news >正文

国外地图搜房网站建设做网站设计的总结

国外地图搜房网站建设,做网站设计的总结,长春是几线城市2020,wordpress支持哪一版本php难以置信#xff0c;一个小小的需求让我捣鼓出一个提效的网站来 需求介绍 事情是这样的#xff0c;有个群友在业务当中碰到一个小小的需求#xff0c;需求是这样的: 页面当中存在多个输入框#xff0c;输入框的 value 值是一个数值组成的字符串#xff08;盲猜应该是身份…难以置信一个小小的需求让我捣鼓出一个提效的网站来 需求介绍 事情是这样的有个群友在业务当中碰到一个小小的需求需求是这样的: 页面当中存在多个输入框输入框的 value 值是一个数值组成的字符串盲猜应该是身份证号码这个字符串的位数是 15 位或者是 18 位例如:621848063680370(15 位)和621848063688370808(18 位)然后默认的值是这样的现在问题来了需求希望在这些数值中插入空白符号比如 15 位的数字就按照 6 6 3 的格式分隔分隔的时候需要使用空白符号。比如621848063680370分隔后应该变成621848 063680 370,也就是数字位数到了第 6 位就加个空白符号分隔...依次类推而 18 位数字的分割规则则是:6 4 4 4。比如621848063688370808应该分隔成621848 0636 8837 0808。 这个需求就是对字符串的处理提到分隔替换那么我们就可以想到强大的字符串替换方法 replace这个方法可以接受 2 个参数一个参数通常是一个正则表达式第二个参数则是一个回调函数用于定义替换后返回字符串。因此我的第一个想法就是使用正则表达式去处理如何处理呢 原理分析 首先我们需要去理解这个规则从需求我们可以发现不同的位数规则就会有所不同因此我们可以提前用一个数据来表示这种规则为了保持良好的扩展性我设计了如下字段: type spaceRule {digit: number; // 位数rule: RegExp; //规则symbolNumber: number; // 插入符号数量symbolName: string; // 插入符号 };可以看到我设计了四个参数正如注释所说每一个参数都有具体的含义,为什么要如此设计参数呢还是看需求我们需求首先是限定了数字的位数只可能是 15 位或者是 18 位那如果存在 19 位又或者 20 位的场景呢因此我们需要设计一个位数的参数然后是每一个位数对应的规则是不一样的因此我们也需要设计一个 rule 参数然后是插入符号数量也许会存在 1 个空白2 个空白等等场景或者我们不一定插入空白符号也有可能是其它符号例如-等等因此就设计 symbolNumber 和 symbolName 参数。 既然规则是类似 6 6 3 这样的规则因此我们想到使用正则表达式来完成这个功能是可以的我们将其拆分开来分成 3 个分组第一个分组匹配 6 个数字第二个分组匹配 6 个数字第三个分组匹配 3 个数字然后针对分组之间插入特定的符号即可。 正则表达式中匹配数字可以使用\d来表示然后匹配位数位 6我们就可以使用量词{6,}来表示因此我们的 6 6 3 规则就可以写成如下: const rule /(\d{6,})(\d{6,})(\d{3,})/g;replace方法核心参数 接下来根据 mdn 对 replace 第二个参数回调函数参数的介绍我们就知道如果匹配到了正则表达式则回调函数的参数会是如下所示: function replacer(match, p1, p2, /* …, */ pN, offset, string, groups) {return replacement; }其中 p1,p2...pN 就是我们这里需要用到的匹配分组有个专业的名词叫做捕获组前面 9 个捕获组对应的就是正则表达式实例对象的$1....$9 属性。 然后其返回值就会用作字符串被替代的部分因此这里我们可以使用展开运算符将中间的捕获组截取出来然后利用 join 方法传入需要插入的符号即可转成符合需求的字符串。 ps: 由于这里经过我对谷歌浏览器的测试replacer 的倒数第 3 个参数不存在因此我这里截取结束索引值就是 args.length - 2。 因此我们可以写出如下代码: const spaceRule {digit: 15,rule: /(\d{6,})(\d{6,})(\d{3,})/g,symbolNumber: 1,symbol: , }; const allInputs document.querySelectorAll(input); allInputs.forEach((item) {const v item.value;const { symbolNumber, symbol, rule } spaceRule;item.value v.replace(rule, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber))); });这样就达到了将输入框中 15 位数字中间插入符号的需求并且满足 6 6 3 的规则。如果是 18 位数字规则也变成了 6 4 4 4我们就只需要修改 digit 和 rule 值即可如下: const spaceRule {digit: 18,rule: /(\d{6,})(\d{4,})(\d{4,})(\d{4,})/g,symbolNumber: 1,symbol: , }; const allInputs document.querySelectorAll(input); allInputs.forEach((item) {const v item.value;const { symbolNumber, symbol, rule } spaceRule;item.value v.replace(rule, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber))); });可以看到我们核心的替换逻辑是没有变动的变动的只是我们定义的规则而已哪怕是用在 vue 和 react 框架当中我们也只是修改一些框架特定的语法但其实核心替换逻辑还是不会变动比如 vue2 代码如下: const spaceRule {digit: 18,rule: 6 4 4 4,symbolNumber: 1,symbol: , }; export default {methods: {onFormatValue(item) {const { symbolNumber, symbol, rule } spaceRule;const regExp new RegExp(${rule.split().map((item) (\\d{${Number(item)},})).reduce((res, item) ((res item), res), )},g);const formatValue item.replace(regExp, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber)));return formatValue;},}, };vue3 代码如下: const spaceRule {digit: 18,rule: 6 4 4 4,symbolNumber: 1,symbol: , }; const onFormatValue computed(() (item) {const { symbolNumber, symbol, rule } spaceRule;const regExp new RegExp(${rule.split().map((item) (\\d{${Number(item)},})).reduce((res, item) ((res item), res), )},g);const formatValue item.replace(regExp, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber)));return formatValue; });react 代码如下: const spaceRule {digit: 18,rule: 6 4 4 4,symbolNumber: 1,symbol: , }; const FormatInput () {const onFormatValue React.useCallback((value) {const { symbolNumber, symbol, rule } spaceRule;const regExp new RegExp(${rule.split().map((item) (\\d{${Number(item)},})).reduce((res, item) ((res item), res), )},g);const formatValue value.replace(regExp, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber)));return formatValue;}, []);return input typetext value{onFormatValue(621848063688370808)} /; }; export default FormatInput;纵观以上的代码我们可以发现核心的 js 逻辑是没有变动的变动的只是一些框架有的概念而已例如 vue2 中我们使用方法结合双向绑定指令 v-model 来修改而 react 也是同理vue3 我们则是使用计算属性来表示。 网站介绍 基于以上的分析接下来就是我们这个提效网站实现的雏形首先来看一下网站如下图所示: 截图截的不全更详细可以点这里查看。 通过以上的网站展示我们已经初步构思好了整个网站的构架: 创建规则的表单部分。预览效果部分。代码展示部分。 其中代码展示部分又提供了不同框架和原生版本的展示以及复制同样的还提供了在线示例的下载其它就是一些额外展示功能组件没什么可说的比如底部链接展示头部组件还有就是需求介绍展示组件。 核心原理我们已经知道了接下来无非就是写好页面架构技术选型上我们使用的是 vue3 vite naive-ui 组件库。 重点代码分析 核心页面我们也不必要介绍这里只重点提一下一些重要功能的实现点首先是代码压缩包的下载我们采用的是 file-saver 和 jszip 库代码很简单如下所示: const zip new JSZip(); zip.file(${codeTypeValue.value}-demo.html,htmlTemplate(renderTemplateCode.value.html,renderTemplateCode.value.js,codeTypeValue.value) ); // 调用zip的generateAsync生成一个blob文件 const content await zip.generateAsync({ type: blob }); // saveAs 方法实现下载 saveAs(content, ${codeTypeValue.value}-demo.zip);其实这里的 htmlTemplate 就是构造一个下载代码模板如下所示: import { CodeTemplateKey } from ./code;export const getScriptTemplate (type: CodeTemplateKey) {if (type.includes(vue)) {const src type vue2? https://cdn.bootcdn.net/ajax/libs/vue/2.6.7/vue.min.js: https://cdn.bootcdn.net/ajax/libs/vue/3.3.4/vue.global.min.js;return script src${src}/script;} else if (type react) {return script srchttps://cdn.bootcdn.net/ajax/libs/react/18.2.0/umd/react.production.min.js/scriptscript srchttps://cdn.bootcdn.net/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js/scriptscript srchttps://cdn.bootcdn.net/ajax/libs/babel-standalone/7.22.17/babel.min.js/script;} else {return ;} }; export const htmlTemplate (htmlContent: string,jsContent: string,type: CodeTemplateKey ) !DOCTYPE html html headmeta charsetutf-8meta nameviewport contentwidthdevice-widthtitle输入框生成插入符号 ${type} demo/titlestylebody {margin: 0;}input {padding: 8px 24px;border: 0;border-radius: 15px;background-color: #fefefe;color: rgba(0, 0, 0, .85);margin: 8px 0;border: 1px solid #232323;min-width: 250px;}/style /head bodydiv idapp${htmlContent}/div${getScriptTemplate(type)}script type${type react ? text/babel : text/javascript}${jsContent}/script /body /html;代码模板如下: export const codeTemplate {js: (options: IFormValue) ({html: Array.from({ length: options.inputNumber }).map((_, i) options.inputContent[i]).map((item) input typetext value${item}/\n).join(),js: const spaceRule {digit: ${options.digit},rule: /${options.rule.split().map((item) (\\d{${Number(item)},})).reduce((res, item) ((res item), res), )}/g,symbolNumber: ${options.symbolNumber},symbol: ${options.symbol} }; const allInputs document.querySelectorAll(input); allInputs.forEach(item {const v item.value;const { symbolNumber, symbol, rule } spaceRule;item.value v.replace(rule, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber))); }),}),vue2: (options: IFormValue) ({html: Array.from({ length: options.inputNumber }).map((_, i) options.inputContent[i]).map((_) input typetext v-modelonFormatValue(${_}) /\n).join(),js: const spaceRule {digit: ${options.digit},rule: ${options.rule},symbolNumber: ${options.symbolNumber},symbol: ${options.symbol} }; export default {methods:{onFormatValue(item){const { symbolNumber,symbol,rule } spaceRule;const regExp new RegExp(\\${rule.split().map(item \(\\\\d{\$\{Number(item)\},})\).reduce((res, item) (res item, res), )}\, g);const formatValue item.replace(regExp, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber)));return formatValue;}} },}),vue3: (options: IFormValue) ({html: Array.from({ length: options.inputNumber }).map((_, i) options.inputContent[i]).map((_) input typetext :valueonFormatValue(${_}) /\n).join(),js: const spaceRule {digit: ${options.digit},rule: ${options.rule},symbolNumber: ${options.symbolNumber},symbol: ${options.symbol} }; const onFormatValue computed(() (item) {const { symbolNumber,symbol,rule } spaceRule;const regExp new RegExp(\\${rule.split().map(item \(\\\\d{\$\{Number(item)\},})\).reduce((res, item) (res item, res), )}\, g);const formatValue item.replace(regExp, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber)));return formatValue; }),}),react: (options: IFormValue) ({html: ,js: const spaceRule {digit: ${options.digit},rule: ${options.rule},symbolNumber: ${options.symbolNumber},symbol: ${options.symbol} }; const FormatInput () {const onFormatValue React.useCallback((value) {const { symbolNumber,symbol,rule } spaceRule;const regExp new RegExp(\\${rule.split().map(item \(\\\\d{\$\{Number(item)\},})\).reduce((res, item) (res item, res), )}\, g);const formatValue value.replace(regExp, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber)));return formatValue;},[])return (${Array.from({ length: options.inputNumber }).map((_, i) options.inputContent[i]).map((_) input typetext value{onFormatValue(${_})} /).join()}) } export default FormatInput;,}), };export const demoCodeTemplate {js: (options: IFormValue) ({html: Array.from({ length: options.inputNumber }).map((_, i) options.inputContent[i]).map((item) input typetext value${item}/\n).join(),js: const spaceRule {digit: ${options.digit},rule: /${options.rule.split().map((item) (\\d{${Number(item)},})).reduce((res, item) ((res item), res), )}/g,symbolNumber: ${options.symbolNumber},symbol: ${options.symbol} }; const allInputs document.querySelectorAll(input); allInputs.forEach(item {const v item.value;const { symbolNumber, symbol, rule } spaceRule;item.value v.replace(rule, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber))); }),}),vue2: (options: IFormValue) ({html: Array.from({ length: options.inputNumber }).map((_, i) options.inputContent[i]).map((_) input typetext v-modelonFormatValue(${_}) /\n).join(),js: const spaceRule {digit: ${options.digit},rule: ${options.rule},symbolNumber: ${options.symbolNumber},symbol: ${options.symbol} }; new Vue({el:#app,methods:{onFormatValue(item){const { symbolNumber,symbol,rule } spaceRule;const regExp new RegExp(\\${rule.split().map(item \(\\\\d{\$\{Number(item)\},})\).reduce((res, item) (res item, res), )}\, g);const formatValue item.replace(regExp, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber)));return formatValue;}} });,}),vue3: (options: IFormValue) ({html: Array.from({ length: options.inputNumber }).map((_, i) options.inputContent[i]).map((_) input typetext :valueonFormatValue(${_}) /\n).join(),js: const spaceRule {digit: ${options.digit},rule: ${options.rule},symbolNumber: ${options.symbolNumber},symbol: ${options.symbol} }; Vue.createApp({setup() {const onFormatValue Vue.computed(() (item) {const { symbolNumber,symbol,rule } spaceRule;const regExp new RegExp(\\${rule.split().map(item \(\\\\d{\$\{Number(item)\},})\).reduce((res, item) (res item, res), )}\, g);const formatValue item.replace(regExp, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber)));return formatValue;})return {onFormatValue}}}).mount(#app),}),react: (options: IFormValue) ({html: ,js: const spaceRule {digit: ${options.digit},rule: ${options.rule},symbolNumber: ${options.symbolNumber},symbol: ${options.symbol} }; const FormatInput () {const onFormatValue React.useCallback((value) {const { symbolNumber,symbol,rule } spaceRule;const regExp new RegExp(\\${rule.split().map(item \(\\\\d{\$\{Number(item)\},})\).reduce((res, item) (res item, res), )}\, g);const formatValue value.replace(regExp, (...args) args?.slice(1, args.length - 2)?.join(symbol.repeat(symbolNumber)));return formatValue;},[])return (${Array.from({ length: options.inputNumber }).map((_, i) options.inputContent[i]).map((_) input typetext value{onFormatValue(${_})} /).join()}) } const root ReactDOM.createRoot(document.querySelector(#app)); root.render(FormatInput /);,}), };export type CodeTemplateKey keyof typeof codeTemplate;// 代码key列表 export const codeTypeList Object.keys(codeTemplate) as CodeTemplateKey[];// 代码版本下拉列表 export const selectCodeTypeList codeTypeList.map((item) ({label: item,value: item, }));然后就是我们的 copy 复制代码功能函数的实现原理就是利用了 navigator.clipboard api,如果浏览器不支持我们就使用 document.execCommand api,工具函数代码如下所示: export const copyHandler (str: string, dialog?: DialogApi) {const confirm (title 温馨提示, content 已复制到剪切板) {dialog?.success({title: title,content: content,positiveText: 确定,});};const baseCopy (copyText: string) new Promisevoid((resolve, reject) {// 判断是否存在clipboard并且是安全的协议if (navigator.clipboard window.isSecureContext) {navigator.clipboard.writeText(copyText).then(() {resolve();}).catch(() {reject(new Error(复制失败));});} else {// 否则使用被废弃的execCommandconst input document.createElement(input) as HTMLInputElement;input.value copyText;// 使input不在viewport同时设置不可见input.style.position absolute;input.style.left -9999px;input.style.top -9999px;document.body.append(input);input.focus();input.select();// 执行复制命令并移除文本框if (document.execCommand) {document.execCommand(copy);resolve();} else {reject(new Error(复制失败));}input.remove();}});baseCopy(str).then(() confirm()).catch(() confirm(温馨提示, 复制失败)); };遇到的有意思的问题分析 除此之外其它都是一些很好理解的基础代码因此不需要讲解这里讲一个让我觉得有意思的问题也是在源码当中有备注那就是被代理的对象会被污染可以看到我们的 config.ts 里面写了 2 个最基础的表单配置对象: export const defaultFormValue {digit: 15,rule: 6 6 3,symbol: ,symbolNumber: 1,inputNumber: 1,inputContent: [621848063680370], }; export const baseDefaultFormValue {digit: 15,rule: 6 6 3,symbol: ,symbolNumber: 1,inputNumber: 1,inputContent: [621848063680370], };用来设置表单的初始值对象我在监听用户修改输入框值之后去改变绑定的初始值发现绑定的初始值被修改污染了哪怕我采用了复制对象副本(使用 JSON 和展开运算符来复制)都会修改原始配置对象。我们的表单配置对象是这样的: const formValue ref({ ...defaultFormValue });也就是说我对 formValue 的修改会影响到 defaultFormValue这就让我感觉很奇怪所以我想创建一个 baseDefaultFormValue 的方式去解决这个问题这样我在重置表单数据的时候就能够重置为最初始的数据如下: const handleResetClick () {formRef.value?.restoreValidation();// 不重新写一个defaultFormValue已经被污染了formValue.value {...baseDefaultFormValue,};emit(on-submit, formValue.value); };这个问题目前我还没有分析出原因来如果有感兴趣的大佬可以通过参考源码调试看看问题我就没有时间去研究这个问题呢。 这些点是我觉得值得分析的地方其它就没啥了感谢阅读到这里如果觉得有帮助可以点赞收藏顺带可以帮我的项目点个 star,感激不尽。 另外给大家整理一部分大厂的面经和一些真题加上一些项目 转发本文关注私信【学习】或添加下方下助理即可领取更多资料
http://www.zqtcl.cn/news/150931/

相关文章:

  • 新网站应该怎么做seo品牌推广方案思维导图
  • 想要网站导航推广页浅谈中兴电子商务网站建设
  • 免费引流在线推广成都网站优化费用
  • 老河口市网站佛山市点精网络科技有限公司
  • word模板免费网站seo引擎优化是做什么的
  • 办网站怎么赚钱鄠邑建站 网站建设
  • 宜春网站建设推广微信小程序开发
  • 巴南城乡建设网站免费网站建设软件大全
  • 湖南网站建设公公司没有自己的网站
  • 刚建设的网站如何推广网站恢复正常
  • 怎么做制作网站的教程永久免费空间免备案
  • 网站维护运营怎么做简单的手机网址大全
  • 网站建设规划设计公司排名使用模块化的网站
  • 南宁网站seo大概多少钱门户网站建设公司渠道
  • 如何建国际商城网站海门做网站公司
  • 做网站应该画什么图注册子公司流程及所需资料
  • 嵊州市建设银行网站怎么自己做游戏软件
  • 用模板快速建站中园建设银行网站
  • 网站建设罒金手指下拉壹陆韩国最新新闻消息
  • 东莞企业网站推广技巧wordpress怎么汉化
  • 17网站一起做网店如何下单iis服务器网站301重定向怎么做
  • 网站如何做线上支付功能seo网站推广优化费用
  • 贵州灵溪seo整站优化wordpress进行不
  • 三网一体网站建设网站开发环境分析
  • 广州白云机场网站建设查询域名备案信息
  • 苗族网站建设中牟做网站
  • 潍坊网站建设建站哪个网站的课件做的好处
  • 网站建设平台杭州网上交易平台
  • 您提交的网站域名无备案我想学网站建设
  • 怎样做国际网站dw网页设计代码免费