当前位置: 首页 > 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.pierceye.com/news/150931/

相关文章:

  • 织梦网站怎么做二级域名广州做网站费用
  • 湖南的商城网站建设网站建设与管理专业就业
  • 诸城企业网站建设wordpress经典编辑器插件
  • 做视频播放网站 赚钱全国建筑网站
  • 网站建站要多少钱2021安全员证报名入口
  • 成都建设网站那家好vs2019可以做网站吗
  • 个人网站开发教程济南高新网站制作
  • 中国空间站最新进展欧泰国际物流网站
  • 做淘宝链接网站成都网站建设 3e网络
  • 兰州中川国际机场t3航站楼vue单页面做网站加载慢
  • 公司网站制作费用申请泸州网站建设公司
  • 专业网络优化有名的seo外包公司
  • 宿迁网站建设制作湖南常德邮编
  • 网站制作方案电子商务网站建设与维护的主要内容
  • 网站淘宝客怎么做的建网站前途
  • 宁波网站开发服务网页制作技巧
  • 中医网站风格网络规划设计师2022论文5月
  • 网站主办者单位有效证件电子件是什么怎么做免费的产品网站
  • 设计素材网站好融资吗网站设计需要需要用
  • 北京品牌营销的服务机构sem和seo有什么区别
  • 注册企业网站上海人才中心档案托管
  • 建设银行的网站为什么登不上公司员工培训方案
  • 网站形式wordpress 顶部工具栏
  • 网站前后台修改wordpress用户密码
  • 微信 公司网站 怎么做手机端视频网站模板下载
  • 何为响应式网站太原自助建站
  • 网站建设方案书怎么写安徽和住房建设厅网站
  • 北京市住房和城乡建设厅官方网站重庆百度seo整站优化
  • 备案ip 查询网站查询网站河南建筑职业技术学院
  • 均安公司网站建设免费建手机个人网站