f9yx0du 发表于 2024-10-3 11:01:10

云鸽笔记|技术复盘与总结


    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">点击「京东数科技术说」可快速关注</span></p><img src="https://mmbiz.qpic.cn/mmbiz_jpg/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqedqqe2PYaUPwxIA6pR2g0gXaZTxhZbImwZVhXBpLkIBKXm9Zep9xwibyQ/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;">
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;">「摘要」</span></strong></span><span style="color: black;">在<span style="color: black;">平常</span>工作和生活中,写笔记、做文件备份都是非常重要的活动,<span style="color: black;">咱们</span><span style="color: black;">亦</span>本着<span style="color: black;">这般</span>的想法,搭建了在<span style="color: black;">机构</span>内部场景下<span style="color: black;">运用</span>的笔记平台——云鸽笔记。如笔记平台的名字<span style="color: black;">通常</span>,<span style="color: black;">期盼</span>平台上的笔记能给<span style="color: black;">咱们</span>的工作带来<span style="color: black;">更加多</span><span style="color: black;">方便</span>的信息共享、思想碰撞。</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">本着信息共享、实现协作的想法,<span style="color: black;">咱们</span>从用户<span style="color: black;">运用</span>场景和习惯出发,分别实现了便于工作时间快速操作的PC端、方便非工作时间快速查阅工作信息的M端,以及用来实现多人员协作的云协作。</span></p><span style="color: black;">1</span><strong style="color: blue;"><span style="color: black;">云鸽笔记的生态</span></strong>
    <h3 style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://mmbiz.qpic.cn/mmbiz_jpg/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqedubFI0RoJHCIo9Kf8iatbzxfadcGgRiagRwV7xDHnspQEEVy4IeXODGnw/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;"></h3><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">1、</span>生态</span></strong></span><span style="color: black;">云协作:多人员协作、项目资源共享、信息同步、共享编辑、周报管理等;</span><span style="color: black;">云鸽笔记PC端:工作时间、快速操作、随时备忘;</span><span style="color: black;">云鸽笔记M端:非工作时间、快速查阅、随时备忘、操作轻量。</span><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">2、</span>生态图景</span></strong></span><span style="color: black;">云协作、云鸽笔记PC端</span><img src="https://mmbiz.qpic.cn/mmbiz_jpg/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqedzTDAgZPvGwysqy9oBNb8HsFiczAEOV7rpfmWPPy6SUjOVtVK0iaRn3ug/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;">
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">云鸽笔记M端&nbsp;</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_jpg/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqedOjJmTlH8YSBrqbdsfvWK8QdnUiaicSQicnQJCKYrrnLl1sd6GN0fzMG1Q/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">3、</span>生态</span></strong><strong style="color: blue;"><span style="color: black;">路引</span></strong></span><span style="color: black;">云鸽笔记PC端:https://yunge.jd.com</span><span style="color: black;">云鸽笔记M端:进入“京ME”APP,应用下搜索“云鸽笔记”。如<span style="color: black;">没法</span>查到,联系@tongen。</span><span style="color: black;">云协作:https://yunge.jd.com/team</span><span style="color: black;">2</span><strong style="color: blue;"><span style="color: black;">云鸽笔记的项目管理实践</span></strong><span style="color: black;"><strong style="color: blue;"><span style="color: black;">践行敏捷</span></strong></span><span style="color: black;">在<span style="color: black;">全部</span>云鸽笔记的生态中,<span style="color: black;">咱们</span>践行着敏捷<span style="color: black;">研发</span>的理念,实现了小版本的快速迭代和版本更新。从大的<span style="color: black;">制品</span>来看,逐步实现云鸽笔记的PC端、M端,继而是云协作。</span><span style="color: black;">从小的<span style="color: black;">制品</span>功能来看,<span style="color: black;">咱们</span>对<span style="color: black;">制品</span>功能进行了总体的梳理及评级,确定本期要做的功能列表。对本期功能列表进行工时与资源估算,并<span style="color: black;">按照</span>已有人员资源<span style="color: black;">即时</span>间安排,确定迭代版本的每一批功能列表。</span><span style="color: black;">在<span style="color: black;">制品</span>实现中,<span style="color: black;">咱们</span>团队因<span style="color: black;">无</span>测试资源及严格的项目管理资源,便就现有资源做了重新分配,并灵活的将测试放在每一个版本的迭代环节里,<span style="color: black;">亦</span>充分利用了<span style="color: black;">分部</span>资源,在进行<span style="color: black;">制品</span>MVP验证的时候,<span style="color: black;">同期</span>做了必要的测试与优化提需。</span><span style="color: black;"><span style="color: black;">开发</span>人员在<span style="color: black;">每日</span>进行功能<span style="color: black;">研发</span>时,对紧急重要的bugs放在<span style="color: black;">研发</span>计划中,进行必要的代码重构与<span style="color: black;">调节</span>。</span><span style="color: black;">以下图示为<span style="color: black;">咱们</span>实施中的基本方式。</span><img src="https://mmbiz.qpic.cn/mmbiz_jpg/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqedspibubWKA6sWyfZe6oNJNl3dFVTvY7kicyKzJlr6n1Sm3aZhiaFe6Q1yg/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;"><span style="color: black;">3</span><strong style="color: blue;"><span style="color: black;">云鸽笔记的设计理念</span></strong><span style="color: black;">随着移动办公的普及,自带设备移动办公已<span style="color: black;">作为</span>现代办公的重要形式之一。<span style="color: black;">咱们</span>本着<span style="color: black;">处理</span>私域用户工作及学习笔记的管理问题,分享和协作等场景进行设计。</span><span style="color: black;">从<span style="color: black;">制品</span>的架构来看,<span style="color: black;">咱们</span><span style="color: black;">尽可能</span>用简洁的设计语言,功能更加纯粹,减少<span style="color: black;">有些</span><span style="color: black;">繁杂</span>的功能,极力降低用户的<span style="color: black;">运用</span>成本。用<span style="color: black;">有效</span><span style="color: black;">方便</span>的操作方式让信息层级更加清晰,<span style="color: black;">加强</span>用户体验。在视觉维度,<span style="color: black;">经过</span>字体模块的<span style="color: black;">体积</span>对比及其色调明度的变化来给用户<span style="color: black;">供给</span>更加舒适的阅读和记录的线上环境。<span style="color: black;">而后</span><span style="color: black;">经过</span><span style="color: black;">恰当</span>的交互方式减少用户的操作成本和学习成本,缩短用户感知<span style="color: black;">制品</span>的时间,<span style="color: black;">提高</span><span style="color: black;">制品</span>体验。</span><span style="color: black;">4</span><strong style="color: blue;"><span style="color: black;">云鸽笔记的实现框架</span></strong><strong style="color: blue;"><span style="color: black;"><span style="color: black;">1、</span>功能模块</span></strong><span style="color: black;">在<span style="color: black;">这儿</span>,<span style="color: black;">咱们</span>对现有功能模块进行了梳理和展示,<span style="color: black;">重点</span>从列表展示、内容展示、用户操作及账号同步、权限设置多方面展开。而这些功能模块的梳理<span style="color: black;">亦</span>为<span style="color: black;">咱们</span>编写框架<span style="color: black;">供给</span>了依据。</span><img src="https://mmbiz.qpic.cn/mmbiz_jpg/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqed23icqDJfZneEIAVjPOm9ceRgEvcYT6rbRMLvbHF5HKFaj6X1E2loHHA/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;"><img src="https://mmbiz.qpic.cn/mmbiz_png/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqedhfjspeA6o3wdHC3KvM5MdVNITibiaZ4zXnUs9EnibepWcDEG9ReWr3Ficg/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">2、</span>框架设计</span></strong><span style="color: black;">在框架设计中,结合功能模块的梳理,<span style="color: black;">咱们</span>遵循<span style="color: black;">方便</span>、可复用的原则,采用以下框架完成多端设计与<span style="color: black;">研发</span>。</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_jpg/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqedQiayLR0mqoJxpfnribATlCrCckVxepgAM1vExAgOE8ia1AEBTPVObiaSibg/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">前端实施中,采用了React+Mobx+Typescript的技术框架,在每一个功能模块中创建其相应的Service,以用来实现应用层API的封装;在Store中实现<span style="color: black;">基本</span>数据的获取或修改,可用于PC与M两个端,而在PC和M两端,分别实现对应其操作<span style="color: black;">行径</span>的数据store。<span style="color: black;">这般</span><span style="color: black;">咱们</span><span style="color: black;">能够</span>达到通用store在多端的复用,又不会给<span style="color: black;">每一个</span>端带来<span style="color: black;">无</span>负作用的多余代码。</span><span style="color: black;">在UI层面,<span style="color: black;">运用</span>Yep-React组件库,搭配构建工具Rocketact/jdwtool,<span style="color: black;">有效</span>完成项目的构建、页面<span style="color: black;">研发</span>及项目的实时预览。</span><span style="color: black;"><strong style="color: blue;"><span style="color: black;"><span style="color: black;">3、</span><span style="color: black;">照片</span>格式的<span style="color: black;">选取</span></span></strong></span><span style="color: black;"><span style="color: black;">由于</span>在项目中存在各式各样的图标,它们小而多,并且会随着操作<span style="color: black;">行径</span><span style="color: black;">出现</span>色值的改变。综合<span style="color: black;">思虑</span>,<span style="color: black;">咱们</span><span style="color: black;">选取</span><span style="color: black;">运用</span>SVG来<span style="color: black;">掌控</span>图标的<span style="color: black;">表示</span>,<span style="color: black;">更加多</span><span style="color: black;">原由</span>如下:</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">相比传统的<span style="color: black;">照片</span>,尺寸更小,可压缩性更强</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">可伸缩,更清晰</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">方便读取和修改</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">设计软件直接导出</span></p><span style="color: black;">5</span><strong style="color: blue;"><span style="color: black;">云鸽笔记的PC端的问题与优化</span></strong><strong style="color: blue;"><span style="color: black;"><span style="color: black;">1、</span>多个svg<span style="color: black;">运用</span>问题</span></strong>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">svg的<span style="color: black;">运用</span>方式多种多样,适合自己的才是最好的。下面简单介绍下<span style="color: black;">咱们</span>的项目<span style="color: black;">怎样</span>在jdwtool脚手架中<span style="color: black;">运用</span>了svg。<span style="color: black;">由于</span>jdwtool基于webpack打包,<span style="color: black;">因此</span>webpack中必不可少需要<span style="color: black;">增多</span>针对svg的配置。</span><span style="color: black;">代码如</span><span style="color: black;">下:&nbsp;</span></p><span style="color: black;">// webpack.config.js</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> test: /\.svg$/,</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> use: [</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {</p> loader: path.resolve(__dirname, <span style="color: black;">"./fdtsvgloader"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> },</p> <span style="color: black;">"svg-loader"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> ],</p>include: [path.resolve(opts<span style="color: black;">.baseDir</span>, <span style="color: black;">"src"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)],</p> exclude: [path.resolve(opts<span style="color: black;">.baseDir</span>, <span style="color: black;">"src/svginline"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">)]</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">咱们</span>依然<span style="color: black;">运用</span>svg-loader进行svg的处理,但svg-loader返回的是一个<span style="color: black;">包括</span></span><span style="color: black;">attributes</span><span style="color: black;">和</span><span style="color: black;">content</span><span style="color: black;">的对象,<span style="color: black;">没法</span>直接<span style="color: black;">运用</span>。处理后的结果如下代码所示:</span></p>module<span style="color: black;">.exports</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> = {</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> attributes: {</p> xmlns: <span style="color: black;">http://www.w3.org/2000/svg</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> viewBox: <span style="color: black;">0 0 1024 1024</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> },</p> <span style="color: black;">content</span>: <span style="color: black;">&lt;path d="M441.9 167.3l-19.8-19.8c-4.7-4.7-12.3-4.7-17 0L224 328.2 42.9 147.5c-4.7-4.7-12.3-4.7-17 0L6.1 167.3c-4.7 4.7-4.7 12.3 0 17l209.4 209.4c4.7 4.7 12.3 4.7 17 0l209.4-209.4c4.7-4.7 4.7-12.3 0-17z"/&gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">因此呢</span>,在fdt中单独写了一个loader来得到想要的svg格式。代码如下:</span></p><span style="color: black;">// fdtsvgloader.js</span><span style="color: black;">module</span>.exports = <span style="color: black;"><span style="color: black;">function</span>(<span style="color: black;">source</span>) </span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{</p> <span style="color: black;">return</span> <span style="color: black;">
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">`</p> <span style="color: black;">${source}</span>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">var fdtsvg = require(fdt-svg-loader)</p>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> module.exports = fdtsvg(module.exports)</p> `
    </span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">};</p><span style="color: black;">// fdt-svg-loader</span><span style="color: black;">var</span> React = <span style="color: black;">require</span>(<span style="color: black;">"react"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p><span style="color: black;">module</span>.exports = <span style="color: black;"><span style="color: black;">function</span>(<span style="color: black;">svg</span>) </span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{</p> <span style="color: black;">const</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">content = svg.content;</p> <span style="color: black;">return</span> <span style="color: black;"><span style="color: black;">function</span>(<span style="color: black;">props</span>) </span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{</p> <span style="color: black;">const</span> newprops = { <span style="color: black;">viewBox</span>: <span style="color: black;">"0 0 1024 1024"</span>, <span style="color: black;">height</span>: <span style="color: black;">"20px"</span>, <span style="color: black;">fill</span>: <span style="color: black;">"#000"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> };</p> newprops.dangerouslySetInnerHTML = { <span style="color: black;">__html</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">: content };</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">newprops;</p> <span style="color: black;">return</span> React.createElement(<span style="color: black;">"svg"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">, { ...newprops, ...props });</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> };</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">};</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">其中,fdtsvgloader.js中接受的参数即为svg-loader处理后的结果。最后,经过fdt-svg-loader处理后,得到了React创建的svg元素,并<span style="color: black;">包括</span>默认属性viewBox,height以及fill值。<span style="color: black;">因此呢</span><span style="color: black;">咱们</span>在组件中<span style="color: black;">能够</span>如下方式引用svg:</span></p><span style="color: black;">// demo.tsx</span><span style="color: black;">import</span> PptIcon <span style="color: black;">from</span> <span style="color: black;">"@/image/newppt.svg"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p><span style="color: black;">export</span> <span style="color: black;">default</span> <span style="color: black;"><span style="color: black;">class</span> <span style="color: black;">Demo</span> <span style="color: black;">extends</span> <span style="color: black;">Component</span> </span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">render() {</p> <span style="color: black;">return</span> <span style="color: black;"><span style="color: black;">&lt;<span style="color: black;">PptIcon</span> <span style="color: black;">width</span>=<span style="color: black;">"18"</span> <span style="color: black;">height</span>=<span style="color: black;">"18"</span> <span style="color: black;">viewBox</span>=<span style="color: black;">"0 0 27 34"</span> /&gt;</span>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p>}
    </span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">demo中传递的属性便可覆盖默认属性,灵活<span style="color: black;">掌控</span>svg的<span style="color: black;">体积</span>。至此,<span style="color: black;">咱们</span>在项目中愉快的<span style="color: black;">运用</span>svg来<span style="color: black;">掌控</span>各式各样图标的<span style="color: black;">表示</span>。</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_jpg/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqedIiaXicNyNBg4OXZAxF4cdll6zpL1hIU45jom6C0Fka7sD2AZwAT0OOtw/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">然则</span><span style="color: black;">忽然</span>有一天,在一个慵懒的午后,测试<span style="color: black;">朋友</span><span style="color: black;">忽然</span>告诉我,页面中的图标从左边变<span style="color: black;">成为了</span>右边的样子。短暂的惊慌之后,我<span style="color: black;">快速</span>抄起键盘寻找bug的所在之处。</p>
    </span><span style="color: black;">实不相瞒,在做此项目之前,我较少涉猎svg的知识,<span style="color: black;">针对</span>svg并不是很<span style="color: black;">熟练</span>。<span style="color: black;">因此呢</span>,寻找bug的过程中遇到了<span style="color: black;">有些</span>困难和挫折。在较短的时间内并<span style="color: black;">无</span><span style="color: black;">快速</span>找到问题所在,<span style="color: black;">首要</span>想到的是重新更换一下图标(设计软件中导出的图标<span style="color: black;">咱们</span>做过手动处理)。惊奇的<span style="color: black;">发掘</span>,这个<span style="color: black;">办法</span>居然好用,果断完成上线。</span><span style="color: black;">事后慢慢琢磨这个事情,一个svg<span style="color: black;">照片</span>并<span style="color: black;">无</span>受到<span style="color: black;">外边</span>CSS的影响,<span style="color: black;">为何</span>会<span style="color: black;">忽然</span><span style="color: black;">引起</span>问题呢?为了更快的<span style="color: black;">发掘</span>问题,我仔细<span style="color: black;">科研</span>了一下<span style="color: black;">咱们</span>的svg图标的结构,学到了<span style="color: black;">有些</span>关于svg的内容:</span><span style="color: black;">&lt;g&gt;</span><span style="color: black;">该标签<span style="color: black;">表率</span>组合</span><span style="color: black;">&lt;defs&gt;</span><span style="color: black;">定义重用图形</span><span style="color: black;">&lt;polygon&gt;</span><span style="color: black;">定义多边形</span><span style="color: black;">&lt;mask&gt;</span><span style="color: black;">定义蒙层</span><span style="color: black;">&lt;use&gt;</span><span style="color: black;">实现SVG现有图形的重用</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">既然<span style="color: black;">没法</span>直接找到答案,那只好上排除法来寻找问题所在了。最后<span style="color: black;">发掘</span>,问题<span style="color: black;">显现</span>的<span style="color: black;">原由</span>是新引入的图标影响了原有图标。svg互相影响<span style="color: black;">亦</span>真的让我非常震惊。</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">那到底是怎么互相影响的呢?<span style="color: black;">原由</span><span style="color: black;">便是</span>新的图标中定义了一个mask蒙层,属性id为</span><span style="color: black;">mask-2</span><span style="color: black;">。受影响的图标中,path标签的mask属性引用了该</span><span style="color: black;">mask-2</span><span style="color: black;">的蒙层,<span style="color: black;">引起</span>新图标的<span style="color: black;">显现</span>影响了部分旧图标。</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">那样</span><span style="color: black;">针对</span>直接在html中引入svg,浏览器<span style="color: black;">针对</span>重用图标的寻找机制是怎么样的呢?<span style="color: black;">咱们</span>做了如下测试:</span></p> <span style="color: black;">&lt;<span style="color: black;">svg</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">defs</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">linearGradient</span> <span style="color: black;">id</span>=<span style="color: black;">white2black</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">stop</span> <span style="color: black;">offset</span>=<span style="color: black;">"0"</span> <span style="color: black;">stop-color</span>=<span style="color: black;">"white"</span>&gt;&lt;/<span style="color: black;">stop</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">stop</span> <span style="color: black;">offset</span>=<span style="color: black;">"100%"</span> <span style="color: black;">stop-color</span>=<span style="color: black;">"black"</span>&gt;&lt;/<span style="color: black;">stop</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">linearGradient</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">mask</span> <span style="color: black;">id</span>=<span style="color: black;">"opacity"</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">x</span>=<span style="color: black;">"0"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span> <span style="color: black;">fill</span>=<span style="color: black;">"url(#white2black)"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">mask</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">defs</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">id</span>=<span style="color: black;">"back"</span> <span style="color: black;">x</span>=<span style="color: black;">"0"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span> <span style="color: black;">fill</span>=<span style="color: black;">"#d4fcff"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">id</span>=<span style="color: black;">"front"</span> <span style="color: black;">x</span>=<span style="color: black;">"0"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span> <span style="color: black;">fill</span>=<span style="color: black;">"#fcd3db"</span> <span style="color: black;">mask</span>=<span style="color: black;">"url(#opacity)"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">svg</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">svg</span> <span style="color: black;">width</span>=<span style="color: black;">"600"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">defs</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">linearGradient</span> <span style="color: black;">id</span>=<span style="color: black;">white2black</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">stop</span> <span style="color: black;">offset</span>=<span style="color: black;">"0"</span> <span style="color: black;">stop-color</span>=<span style="color: black;">"blue"</span>&gt;&lt;/<span style="color: black;">stop</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">stop</span> <span style="color: black;">offset</span>=<span style="color: black;">"50%"</span> <span style="color: black;">stop-color</span>=<span style="color: black;">"black"</span>&gt;&lt;/<span style="color: black;">stop</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">stop</span> <span style="color: black;">offset</span>=<span style="color: black;">"100%"</span> <span style="color: black;">stop-color</span>=<span style="color: black;">"green"</span>&gt;&lt;/<span style="color: black;">stop</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">linearGradient</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">mask</span> <span style="color: black;">id</span>=<span style="color: black;">"opacity"</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">x</span>=<span style="color: black;">"50"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"600"</span> <span style="color: black;">height</span>=<span style="color: black;">"400"</span> <span style="color: black;">fill</span>=<span style="color: black;">"green"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">mask</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">defs</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">id</span>=<span style="color: black;">"back"</span> <span style="color: black;">x</span>=<span style="color: black;">"0"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span> <span style="color: black;">fill</span>=<span style="color: black;">"#d4fcff"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">id</span>=<span style="color: black;">"front"</span> <span style="color: black;">x</span>=<span style="color: black;">"0"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span> <span style="color: black;">fill</span>=<span style="color: black;">"#fcd3db"</span> <span style="color: black;">mask</span>=<span style="color: black;">"url(#opacity)"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">svg</span>&gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">该代码的展示效果为:</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_jpg/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqedIzVzJCcbQpn4t5AuDZm5E2LOlJ0m4AH4Qt0pyFjgBTuJibuJEKewBYg/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;"></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">当把<span style="color: black;">第1</span>个svg的mask标签删除之后</span></p> <span style="color: black;">&lt;<span style="color: black;">svg</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">defs</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">linearGradient</span> <span style="color: black;">id</span>=<span style="color: black;">white2black</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">stop</span> <span style="color: black;">offset</span>=<span style="color: black;">"0"</span> <span style="color: black;">stop-color</span>=<span style="color: black;">"white"</span>&gt;&lt;/<span style="color: black;">stop</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">stop</span> <span style="color: black;">offset</span>=<span style="color: black;">"100%"</span> <span style="color: black;">stop-color</span>=<span style="color: black;">"black"</span>&gt;&lt;/<span style="color: black;">stop</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">linearGradient</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">defs</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">id</span>=<span style="color: black;">"back"</span> <span style="color: black;">x</span>=<span style="color: black;">"0"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span> <span style="color: black;">fill</span>=<span style="color: black;">"#d4fcff"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">id</span>=<span style="color: black;">"front"</span> <span style="color: black;">x</span>=<span style="color: black;">"0"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span> <span style="color: black;">fill</span>=<span style="color: black;">"#fcd3db"</span> <span style="color: black;">mask</span>=<span style="color: black;">"url(#opacity)"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">svg</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">svg</span> <span style="color: black;">width</span>=<span style="color: black;">"600"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">defs</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">linearGradient</span> <span style="color: black;">id</span>=<span style="color: black;">white2black</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">stop</span> <span style="color: black;">offset</span>=<span style="color: black;">"0"</span> <span style="color: black;">stop-color</span>=<span style="color: black;">"blue"</span>&gt;&lt;/<span style="color: black;">stop</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">stop</span> <span style="color: black;">offset</span>=<span style="color: black;">"50%"</span> <span style="color: black;">stop-color</span>=<span style="color: black;">"black"</span>&gt;&lt;/<span style="color: black;">stop</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">stop</span> <span style="color: black;">offset</span>=<span style="color: black;">"100%"</span> <span style="color: black;">stop-color</span>=<span style="color: black;">"green"</span>&gt;&lt;/<span style="color: black;">stop</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">linearGradient</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">mask</span> <span style="color: black;">id</span>=<span style="color: black;">"opacity"</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">x</span>=<span style="color: black;">"50"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"600"</span> <span style="color: black;">height</span>=<span style="color: black;">"400"</span> <span style="color: black;">fill</span>=<span style="color: black;">"green"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">mask</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">defs</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">id</span>=<span style="color: black;">"back"</span> <span style="color: black;">x</span>=<span style="color: black;">"0"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span> <span style="color: black;">fill</span>=<span style="color: black;">"#d4fcff"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;<span style="color: black;">rect</span> <span style="color: black;">id</span>=<span style="color: black;">"front"</span> <span style="color: black;">x</span>=<span style="color: black;">"0"</span> <span style="color: black;">y</span>=<span style="color: black;">"0"</span> <span style="color: black;">width</span>=<span style="color: black;">"400"</span> <span style="color: black;">height</span>=<span style="color: black;">"300"</span> <span style="color: black;">fill</span>=<span style="color: black;">"#fcd3db"</span> <span style="color: black;">mask</span>=<span style="color: black;">"url(#opacity)"</span>&gt;&lt;/<span style="color: black;">rect</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">svg</span>&gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">效果变为:&nbsp;</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="https://mmbiz.qpic.cn/mmbiz_jpg/g9uU4FY8hdcQNMWMOzcibsgaiaWGMkCqed3JtuS8CMpJk7WQVviaRxXl6Bz9HpRU51CJJ2CupqC5LTtxmIlicibR6rg/640?wx_fmt=jpeg&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1&amp;wx_co=1" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">由此<span style="color: black;">能够</span><span style="color: black;">判断</span>,svg在寻找重用元素时的机制为:在当前HTML环境中寻找<span style="color: black;">第1</span>个匹配的元素。并不是想象中的在svg自己内部寻找<span style="color: black;">或</span>逐层往外寻找。</span><span style="color: black;"><span style="color: black;">因此</span>,在html中直接引入svg必然会存在互相影响的问题,<span style="color: black;">亦</span>必然会带来<span style="color: black;">有些</span>未知的<span style="color: black;">危害</span>。<span style="color: black;">那样</span>到底有<span style="color: black;">无</span>较为安全的<span style="color: black;">方法</span>呢?</span><span style="color: black;"><span style="color: black;">办法</span>总比困难多,<span style="color: black;">处理</span><span style="color: black;">方法</span>肯定是存在的。为了防止互相影响,<span style="color: black;">咱们</span><span style="color: black;">运用</span>css中的bac<span style="color: black;">公斤</span>round-image属性将svg引入,该<span style="color: black;">方法</span>中的svg在寻找重用元素时,仅仅会寻找<span style="color: black;">自己</span>标签内<span style="color: black;">是不是</span>存在,而不会向外寻找,<span style="color: black;">因此呢</span><span style="color: black;">必定</span>程度上<span style="color: black;">保准</span>了svg图标的安全性。</span><span style="color: black;">那以后要<span style="color: black;">始终</span><span style="color: black;">运用</span>该种<span style="color: black;">方法</span>吗?我觉得还是分场景<span style="color: black;">运用</span>最为合适。例如:一成不变的svg图标<span style="color: black;">能够</span>采用css的方式引入,带有交互<span style="color: black;">行径</span>的图标<span style="color: black;">能够</span>采用html的方式引入,方便修改样式。当然,最重要的<span style="color: black;">便是</span>,<span style="color: black;">针对</span>直接<span style="color: black;">运用</span>的图标,svg内最好干净的仅剩下path标签,<span style="color: black;">这般</span>不会带来任何问题。</span><span style="color: black;">当然,svg sprites<span style="color: black;">运用</span>use引用时<span style="color: black;">亦</span>会存在问题。</span><strong style="color: blue;"><span style="color: black;"><span style="color: black;">2、</span>第三方库引用新姿势</span></strong><span style="color: black;">众所周知,React本身<span style="color: black;">举荐</span>两种引用<span style="color: black;">办法</span>,一种是<span style="color: black;">经过</span>HTML的script标签引入React,另一种是<span style="color: black;">运用</span>例如Create-react-app等脚手架<span style="color: black;">起步</span>大型React应用。前者是将React集成到现有项目最简单的方式,而大<span style="color: black;">都数</span>人在<span style="color: black;">运用</span>React框架的时候,<span style="color: black;">常常</span><span style="color: black;">选取</span>后者,<span style="color: black;">由于</span>后者更方便扩展文件和组件的规模,<span style="color: black;">运用</span>npm的第三方库。</span><span style="color: black;">此时,<span style="color: black;">咱们</span>需要将React安装在项目的node_modules中,并写入package.json文件的dependence字段,并<span style="color: black;">运用</span>yarn.lock锁住版本。<span style="color: black;">这般</span>,当多人协作完成项目或更换设备初始化代码时都会将<span style="color: black;">因此</span>依赖<span style="color: black;">根据</span>锁定的版本安装,<span style="color: black;">保准</span>项目的正常运行。这是一种很<span style="color: black;">广泛</span>、很<span style="color: black;">平常</span>的用法,<span style="color: black;">详细</span>内容无需赘述。<span style="color: black;">这里</span>,仅介绍一下<span style="color: black;">咱们</span>的<span style="color: black;">运用</span><span style="color: black;">办法</span>。</span><span style="color: black;"><span style="color: black;">运用</span>script的方式引入React:&nbsp;</span><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;">
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">项目中依然<span style="color: black;">运用</span>:&nbsp;</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">同期</span>并不将React安装到项目依赖中。看到这<span style="color: black;">非常多</span>人会问,编辑器不会提示找不到react吗?我给出你的答案肯定是不会。</p>
    </span><span style="color: black;"><span style="color: black;">为何</span>呢?<span style="color: black;">由于</span>脚手架jdwtool做了一步处理。大家都<span style="color: black;">晓得</span>,import寻找依赖的机制是从当前项目中的node_module<span style="color: black;">起始</span>,依次往父级<span style="color: black;">查询</span>,最后<span style="color: black;">查询</span>到系统目录,<span style="color: black;">倘若</span><span style="color: black;">这里</span>过程中完成匹配,那<span style="color: black;">查询</span>到此为止。显然,引入的react并不会<span style="color: black;">查询</span>到,<span style="color: black;">由于</span>在系统目录<span style="color: black;">亦</span>并未安装,<span style="color: black;">那样</span>到底怎么<span style="color: black;">查询</span>到的呢?这个就需要 tsconfig path 来为<span style="color: black;">咱们</span>助力了。</span><span style="color: black;">使用tsconfig中的path字段进行路径映射,当项目中<span style="color: black;">没法</span>匹配到依赖时,会<span style="color: black;">根据</span>path中给出的字段进行匹配,直到匹配完成。动态生成的path如下:</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其中,映射的路径为xyz,先从x<span style="color: black;">起始</span>,直到z匹配完成。<span style="color: black;">这儿</span>面<span style="color: black;">包括</span>了jdwtool的安装路径,将React安装到了jdwtool的node_modules下。<span style="color: black;">因此呢</span>,项目中import react时,可从jdwtool的node_modules下<span style="color: black;">查询</span>到react,<span style="color: black;">保准</span>项目的正常运行。</p>
    </span><span style="color: black;">下面,<span style="color: black;">能够</span>看一下项目的dependence字段:</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">从图中<span style="color: black;">能够</span>看到,项目中并不会安装<span style="color: black;">有些</span>通用的依赖,所有通用的依赖都安装到了jdwtool下,这<span style="color: black;">便是</span><span style="color: black;">咱们</span>整体的实现思路。</p>
    </span><span style="color: black;">这么做到底有什么好处呢?</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">一次加载,多处<span style="color: black;">运用</span>。加载一次cdn上的react文件,任何请求该文件的项目都可走缓存,而无需请求。</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">方便升级react版本。<span style="color: black;">大众</span>都<span style="color: black;">晓得</span>,react总会给<span style="color: black;">咱们</span>带来<span style="color: black;">非常多</span>惊喜,尝试新版本总是变的迫不及待。<span style="color: black;">运用</span>这种<span style="color: black;">办法</span>,<span style="color: black;">能够</span><span style="color: black;">容易</span>升级react版本,而无需担心重新打包vendor。</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">脚手架安装依赖,项目初始化更快。<span style="color: black;">非常多</span>的依赖都安装在了脚手架中,<span style="color: black;">那样</span>项目中安装的依赖变的非常少,这使得<span style="color: black;">每一个</span>人clone下项目后,无需花费<span style="color: black;">太多</span>的时间等待依赖的安装。</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">脚手架统一升级依赖版本。依赖都安装在脚手架的安装目录下,当需要升级依赖版本时,只需要更新脚手架<span style="color: black;">就可</span>。</span></p><span style="color: black;">看到这<span style="color: black;">亦</span>许有人会问,假如某个项目不想<span style="color: black;">运用</span>脚手架的依赖怎么办?这个只需要在项目中安装指定版本的依赖<span style="color: black;">就可</span>。</span><span style="color: black;"><span style="color: black;">那样</span><span style="color: black;">为何</span>不将antd<span style="color: black;">运用</span>script的方式引入呢?<span style="color: black;">由于</span>antd<span style="color: black;">咱们</span><span style="color: black;">运用</span>了按需加载,而不像react这种全量加载。<span style="color: black;">因此呢</span>,<span style="color: black;">针对</span>需要全量加载的依赖,<span style="color: black;">能够</span>尝试<span style="color: black;">运用</span>这种方式引入。</span><strong style="color: blue;"><span style="color: black;"><span style="color: black;">3、</span>antd icons 按需加载</span></strong><span style="color: black;">前文<span style="color: black;">咱们</span><span style="color: black;">说到</span>过,<span style="color: black;">针对</span>antd这种<span style="color: black;">能够</span>按需加载组件的库,不<span style="color: black;">运用</span>script的方式全量引入。确实,antd支持按需加载组件。实现按需加载组件的方式有两种,一种是单个组件分别引入对应的组件与样式,这种方式代码冗余,<span style="color: black;">因此呢</span><span style="color: black;">更加多</span>人<span style="color: black;">爱好</span>第二种<span style="color: black;">运用</span>babel-plugin-import的方式实现按需加载。第二种<span style="color: black;">详细</span>的实现方式网上案例较多,脚手架<span style="color: black;">亦</span>加入了对antd按需加载的处理,但这不是本段的主旨,本段的主旨是介绍antd中Icon组件的按需加载。</span><span style="color: black;">事情的起因是<span style="color: black;">这般</span>的,<span style="color: black;">咱们</span>引用了一个Icon下的一个图标,<span style="color: black;">而后</span>看了下打包后的体积,<span style="color: black;">发掘</span>增大了好多。于是查看了打包后的内容<span style="color: black;">发掘</span>,antd将所有的Icon的导入了。。。都导入了。。</span><span style="color: black;">看一下antd中Icon组件的源码,其中最引入注目的肯定是这段代码:</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p><span style="color: black;">当调用antd的Icon组件时,会将所有的Icon导入。其实<span style="color: black;">所有</span>导入<span style="color: black;">亦</span>没什么,关键是看一下dist的体积,500kb+。<span style="color: black;">运用</span>了一个Icon需要增大500kb的体积,这显然并不合适。<span style="color: black;">因此呢</span>,<span style="color: black;">咱们</span>要寻找一种<span style="color: black;">处理</span><span style="color: black;">方法</span>。</span><span style="color: black;"><span style="color: black;">首要</span>,在工具类目下创建一个文件,名为icons.ts,内容如下:</span><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><span style="color: black;">icons.ts中<span style="color: black;">咱们</span>默认导出了两个需要<span style="color: black;">运用</span>的图标,<span style="color: black;">况且</span>项目中业仅仅<span style="color: black;">运用</span>了这两个图标。假如想<span style="color: black;">运用</span><span style="color: black;">更加多</span>的图标,<span style="color: black;">那样</span><span style="color: black;">亦</span><span style="color: black;">能够</span>在该文件中写入。</span><span style="color: black;">其次,webpack设置别名alias。<span style="color: black;">由于</span>脚手架中的webpack配置均从toml文件中读取。<span style="color: black;">因此</span>,需要在toml中配置webpack的alias,代码如下:</span><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><span style="color: black;">第三,在项目中正常<span style="color: black;">运用</span>Icon。</span><span style="color: black;"><span style="color: black;">这般</span>一来,当引入Icon时,就把本来要引用的dist指向了自己写的icons.ts。无需<span style="color: black;">所有</span>加载!避免<span style="color: black;">运用</span>一个Icon带来500kb网络开销的<span style="color: black;">包袱</span>。</span><span style="color: black;">6</span><strong style="color: blue;"><span style="color: black;">云鸽笔记的M端的技术难点解析</span></strong><strong style="color: blue;"><span style="color: black;"><span style="color: black;">1、</span>滚动列表的实现</span></strong><span style="color: black;">在M端<span style="color: black;">起始</span>进入<span style="color: black;">研发</span>时,PC端已基本完成。同步PC端的代码库,<span style="color: black;">科研</span>列表<span style="color: black;">发掘</span>,使用了<span style="color: black;">持有</span>虚拟滚动条的 InfiniteLoader 的代码库;在M端尝试<span style="color: black;">运用</span>该库,<span style="color: black;">发掘</span>生成的页面层级过深,页面较<span style="color: black;">繁杂</span>,虽虚拟滚动条看起来会顺畅,<span style="color: black;">咱们</span><span style="color: black;">最后</span>放弃了在M端的应用。</span><span style="color: black;"><span style="color: black;">不外</span><span style="color: black;">咱们</span>还是对 InfiniteLoader 做了进一步理解和尝试。<span style="color: black;">例如</span><span style="color: black;">怎样</span>动态设置行高,<span style="color: black;">怎样</span>屏蔽在首屏数据未加载的<span style="color: black;">状况</span>下唤起下一次数据请求。</span><span style="color: black;">来一波伪代码:</span><span style="color: black;">&lt;<span style="color: black;">InfiniteLoader</span> <span style="color: black;">isRowLoaded</span>=<span style="color: black;">{isRowLoaded}</span> <span style="color: black;">loadMoreRows</span>=<span style="color: black;">{loadmore}</span> <span style="color: black;">rowCount</span>=<span style="color: black;">{count}</span> <span style="color: black;">threshold</span>=<span style="color: black;">{10}</span> <span style="color: black;">minimumBatchSize</span>=<span style="color: black;">{20}</span> &gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{({ onRowsRendered, registerChild }) =&gt; (</p> <span style="color: black;">&lt;<span style="color: black;">AutoSizer</span>&gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {({ height, width }) =&gt; (</p> <span style="color: black;">&lt;<span style="color: black;">List</span> <span style="color: black;">ref</span>=<span style="color: black;">{registerChild}</span> <span style="color: black;">onRowsRendered</span>=<span style="color: black;">{onRowsRendered}</span> <span style="color: black;">deferredMeasurementCache</span>=<span style="color: black;">{cache}</span> <span style="color: black;">rowHeight</span>=<span style="color: black;">{cache.rowHeight}</span> <span style="color: black;">rowRenderer</span>=<span style="color: black;">{rowRenderer}</span> /&gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> )}</p> <span style="color: black;">&lt;/<span style="color: black;">AutoSizer</span>&gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> )}</p> <span style="color: black;">&lt;/<span style="color: black;">InfiniteLoader</span>&gt;</span><span style="color: black;">const</span> rowRenderer = <span style="color: black;">(<span style="color: black;">{ key, index, style, parent }</span>) =&gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {</p> <span style="color: black;">return</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> (</p> <span style="color: black;"><span style="color: black;">&lt;<span style="color: black;">CellMeasurer</span> <span style="color: black;">cache</span>=<span style="color: black;">{cache}</span> <span style="color: black;">columnIndex</span>=<span style="color: black;">{0}</span> <span style="color: black;">key</span>=<span style="color: black;">{key}</span> <span style="color: black;">parent</span>=<span style="color: black;">{parent}</span> <span style="color: black;">rowIndex</span>=<span style="color: black;">{index}</span> &gt;</span> <span style="color: black;">&lt;<span style="color: black;">div</span> <span style="color: black;">className</span>=<span style="color: black;">"infinitelist-item"</span> &gt;</span> <span style="color: black;">&lt;/<span style="color: black;">div</span>&gt;</span> <span style="color: black;">&lt;/<span style="color: black;">CellMeasurer</span>&gt;</span></span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> )</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> };</p><span style="color: black;">其中 CellMeasurer 组件<span style="color: black;">能够</span>实现动态设置元素行高;而threshold 、minimumBatchSize 和 defaultHeight等混合应用<span style="color: black;">才可</span><span style="color: black;">处理</span>不要在首屏首次列表数据未加载完毕时发起再次请求的问题。</span><strong style="color: blue;"><span style="color: black;"><span style="color: black;">2、</span>列表页面切换保持切换前滚动高度</span></strong><span style="color: black;">页面在切换时,能保持原页面的滚动高度,<span style="color: black;">能够</span>大大<span style="color: black;">提高</span>用户体验,不会让用户因在切换之间页面跳来跳去,有<span style="color: black;">失去控制</span>的感觉。</span><span style="color: black;">还是回到刚才的 InfiniteLoader 组件,很强大,<span style="color: black;">供给</span>了上一个页面离开时的滚动高度。<span style="color: black;">不外</span><span style="color: black;">由于</span>已废弃掉该组件在项目中的应用,需要自己来实现。不如把页面滚动和页面<span style="color: black;">转</span>间的关系画下来,按图索骥,便会一目了然。</span><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><span style="color: black;">上图已比较清晰的展示了页面滚动及页面<span style="color: black;">转</span>,只需找个<span style="color: black;">地区</span>把<span style="color: black;">转</span>前页面的scrolltop值存储下来,等再次回到该页面是,再取来去做<span style="color: black;">转</span>就好了。</span><span style="color: black;">以下是伪代码展示:</span><span style="color: black;">// 写</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">setScrollTopByPager(page: string, top: number) {</p> <span style="color: black;">this</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.topHash= top;</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">};</p><span style="color: black;">// 读</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">getScrollTopByPage(page: string) {</p> <span style="color: black;">return</span> <span style="color: black;">this</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.topHash;</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">};</p><span style="color: black;">// 侦听滚动</span>scrollNode.addEventListener(<span style="color: black;">scroll</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">, () =&gt; {</p> <span style="color: black;">this</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.setScrollTopForRoutor(</p> <span style="color: black;">this</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.pageId,</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">scrollNode.scrollTop</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> );</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">})</p><span style="color: black;">// 再次进入页面时读取并设置</span>let top = <span style="color: black;">this</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.getScrollTopByPage(pageId);</p>scrollNode.scrollTo(<span style="color: black;">0</span>, top);<strong style="color: blue;"><span style="color: black;"><span style="color: black;">3、</span>笔记的编辑和预览</span></strong><span style="color: black;"><span style="color: black;">做为</span>云鸽笔记的核心功能,<span style="color: black;">咱们</span>的定位是支持尽可能丰富的笔记格式和文档格式。<span style="color: black;">针对</span>笔记格式,支持常用的富文本及markdown格式,这两种格式<span style="color: black;">供给</span>编辑及预览;<span style="color: black;">针对</span>文档格式,关注下载及预览。</span><span style="color: black;">在编辑器方面,本期优先<span style="color: black;">选取</span>了第三方的编辑器类库,以快速实现MVP的验证。其中富文本编辑器<span style="color: black;">选取</span>了“braft-editor”;MarkDown<span style="color: black;">选取</span><span style="color: black;">运用</span>“tui-editor”。</span><span style="color: black;"><span style="color: black;">由于</span><span style="color: black;">日前</span>两者都比较成熟,<span style="color: black;">运用</span>较为简单,可<span style="color: black;">更加多</span>关注内容的实现。</span><span style="color: black;">在文件预览方面,<span style="color: black;">咱们</span><span style="color: black;">供给</span>较为丰富的文件格式的在线预览,如<span style="color: black;">大众</span>常用的Office系列文档格式、PDF格式,以及<span style="color: black;">照片</span>,还有<span style="color: black;">做为</span>程序员常用的代码类文件格式。</span><span style="color: black;">在设定<span style="color: black;">目的</span>及初步<span style="color: black;">处理</span><span style="color: black;">方法</span>后,<span style="color: black;">咱们</span>在实施过程中<span style="color: black;">亦</span>遇到了<span style="color: black;">有些</span>问题,有些<span style="color: black;">亦</span>是兼容性问题,以下一一展开。</span><strong style="color: blue;"><span style="color: black;"><span style="color: black;">4、</span>M</span></strong><strong style="color: blue;"><span style="color: black;">D 和富文本编辑</span></strong><span style="color: black;">问题一:markdown和富文本编辑器在编辑状态下,<span style="color: black;">没法</span>滚动到底部,有一部分被手机键盘遮挡。</span><span style="color: black;"><span style="color: black;">原由</span>在于 android 和 iOS 在键盘弹起和收起时页面的<span style="color: black;">行径</span>是完全不<span style="color: black;">同样</span>的——</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;"><span style="color: black;">iOS</span></strong><span style="color: black;">:iOS的键盘在窗口的最上层,当键盘弹起时,webview的高度并不会<span style="color: black;">出现</span>变化,<span style="color: black;">然则</span>scrollTop会<span style="color: black;">出现</span>变化,页面<span style="color: black;">出现</span>滚动,而页面可滚动的最大高度是弹出的键盘的高度;且<span style="color: black;">仅有</span>当键盘弹起时页面滚动到底部时, scrollTop 的变化值才为键盘高度。</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><strong style="color: blue;"><span style="color: black;">Android</span></strong><span style="color: black;">:webview留出键盘空间,键盘弹起时页面高度会改变,内容区域会减少,页面不会<span style="color: black;">出现</span>滚动,flex布局下会压缩页面。</span></p><span style="color: black;">针对iOS下这种<span style="color: black;">状况</span>,<span style="color: black;">各样</span>社区<span style="color: black;">亦</span><span style="color: black;">供给</span>了<span style="color: black;">非常多</span>的<span style="color: black;">处理</span><span style="color: black;">方法</span>,基本都是关于input标签fixed布局失效的案例,<span style="color: black;">然则</span><span style="color: black;">咱们</span>的场景比较特殊,笔记编辑的时候<span style="color: black;">全部</span>内容区域都是可编辑区,这就<span style="color: black;">引起</span>总有一部分内容会被键盘挡住<span style="color: black;">没法</span>被看见和选中编辑。</span><span style="color: black;"><span style="color: black;">亦</span>尝试过<span style="color: black;">运用</span>以下方式</span><span style="color: black;">input</span><span style="color: black;">.scrollIntoView</span>(<span style="color: black;">true</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p><span style="color: black;">input</span><span style="color: black;">.scrollIntoViewIfNeeded</span>();<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">另一</span><span style="color: black;">咱们</span><span style="color: black;">期盼</span>笔记标题在顶部固定,内容区域和可编辑区域可滚动,<span style="color: black;">因此呢</span>采用了flex布局。但场景中可编辑区<span style="color: black;">已然</span><span style="color: black;">处在</span>可视区域,<span style="color: black;">因此</span>并没能<span style="color: black;">处理</span>问题,还有重要的一点是键盘弹起之后编辑区域<span style="color: black;">亦</span>是可滚动的,依然会<span style="color: black;">有没有</span>法滚动到底部的问题,键盘还是会遮挡一部分内容。</span></p><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><span style="color: black;">这种场景并不<span style="color: black;">同样</span>,</span><span style="color: black;">经过几番尝试均未达到想要的效果,于是尝试改变布局<span style="color: black;">方法</span>,不<span style="color: black;">运用</span>flex布局,<span style="color: black;">运用</span>最简单的流体布局,监听页面滚动,动态固定笔记标题。</span> <span style="color: black;">let</span> noteHeader = <span style="color: black;">document</span>.querySelector(<span style="color: black;">.note-header</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p> <span style="color: black;">window</span>.addEventListener(<span style="color: black;">scroll</span>, <span style="color: black;">this</span>.scrollFn, <span style="color: black;">false</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p> <span style="color: black;">this</span>.scrollFn = <span style="color: black;"><span style="color: black;">()</span> =&gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {</p> <span style="color: black;">let</span> positionTop = <span style="color: black;">document</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.body.scrollTop;</p> noteHeader.style.top = positionTop + <span style="color: black;">px</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p> }<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;">这般</span>能让标题固定在顶部,由js动态<span style="color: black;">掌控</span>,体验上差<span style="color: black;">有些</span>。键盘遮挡内容的问题还是<span style="color: black;">无</span><span style="color: black;">处理</span>,经过反复的实验,<span style="color: black;">发掘</span>其实<span style="color: black;">全部</span>内容区域并<span style="color: black;">无</span>滚动上去,键盘下面的位置还有一部分内容,<span style="color: black;">因此呢</span>需要在键盘弹起的时候将内容向上顶起,使这部分内容<span style="color: black;">处在</span>键盘上方,<span style="color: black;">亦</span><span style="color: black;">便是</span>在键盘弹起后给内容区域加</span><span style="color: black;">&nbsp;paddingBottom&nbsp;</span><span style="color: black;">属性,键盘下面区域用空白填充,内容<span style="color: black;">就可</span>滚动到键盘上方,先来实验一下。</span></p><span style="color: black;">let</span> focusinFn = <span style="color: black;"><span style="color: black;">()</span> =&gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{</p> <span style="color: black;">let</span> content = <span style="color: black;">document</span>.querySelector(<span style="color: black;">.content</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p> content.style.paddingBottom = <span style="color: black;">7.5rem</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">;</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">}</p><span style="color: black;">window</span>.addEventListener(<span style="color: black;">focusin</span>, focusinFn, <span style="color: black;">false</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p><span style="color: black;">实验成功,<span style="color: black;">能够</span><span style="color: black;">根据</span>这个思路继续优化了,这期是<span style="color: black;">根据</span>常规的最高键盘高度来设置的</span><span style="color: black;">paddingBottom</span><span style="color: black;">值来实现这个效果,键盘收起的时候重置成初始的状态,后续优化这快高度的设置。</span><span style="color: black;">这块的实现比较粗糙,还有很大的优化空间,或许还有更好的<span style="color: black;">处理</span><span style="color: black;">方法</span>。以此抛砖引玉,<span style="color: black;">期盼</span>看到<span style="color: black;">大众</span>的想法。</span><strong style="color: blue;"><span style="color: black;"><span style="color: black;">5、</span>PDF 和 Office 文件预览</span></strong><span style="color: black;">问题二:office文件预览,<span style="color: black;">没法</span>放大缩小,上层样式的影响<span style="color: black;">没法</span>滚动;</span><span style="color: black;">问题三:pdf存在<span style="color: black;">没法</span>滚动和缩放的问题,体验很差。</span><span style="color: black;"><span style="color: black;">原由</span><span style="color: black;">重点</span>是<span style="color: black;">运用</span>html标签在页面中渲染<span style="color: black;">没法</span>缩放和滚动。</span><span style="color: black;">在预览PDF中,<span style="color: black;">运用</span>了</span><span style="color: black;">&nbsp;embed&nbsp;</span><span style="color: black;">标签加载;而Office文件<span style="color: black;">运用</span>了</span><span style="color: black;">&nbsp;iframe&nbsp;</span><span style="color: black;">加载。</span><span style="color: black;">但<span style="color: black;">没法</span>滚动和缩放,使阅读体验大打折扣。后来<span style="color: black;">咱们</span>改进了此<span style="color: black;">办法</span>,先下载文件,再<span style="color: black;">运用</span>手机的文件预览功能打开文档进行预览,实验成功。而收获的意外体验是,<span style="color: black;">此时</span><span style="color: black;">能够</span>友好的提示用户<span style="color: black;">是不是</span>要下载当前文档,给了用户<span style="color: black;">更加多</span>的<span style="color: black;">掌控</span>权。</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">axios({</p> <span style="color: black;">method</span>: <span style="color: black;">"get"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">url</span>: <span style="color: black;">`downloadurl`</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">responseType</span>: <span style="color: black;">"blob"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">,</p> <span style="color: black;">onDownloadProgress</span>: <span style="color: black;">(<span style="color: black;">progressEvent</span>) =&gt;</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> {</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> onDownloadProgress &amp;&amp; onDownloadProgress(progressEvent);</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> }</p> }).then(<span style="color: black;"><span style="color: black;">function</span>(<span style="color: black;">response</span>) </span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">{</p> <span style="color: black;">var</span> a = <span style="color: black;">document</span>.createElement(<span style="color: black;">"a"</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">);</p> <span style="color: black;">var</span> url = <span style="color: black;">window</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.URL.createObjectURL(response.data);</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> a.href = url;</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> a.download = name;</p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"> a.click();</p> <span style="color: black;">window</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">.URL.revokeObjectURL(url);</p> });<strong style="color: blue;"><span style="color: black;"><span style="color: black;">6、</span>与京ME应用的打通</span></strong><span style="color: black;"><span style="color: black;">咱们</span>的<span style="color: black;">制品</span>定位是基于内部私域的实现,<span style="color: black;">因此</span>在账号体系的打通上我们<span style="color: black;">运用</span>了<span style="color: black;">机构</span>的ERP账号体系。而京ME是基于全员的<span style="color: black;">必须</span>APP,<span style="color: black;">亦</span>是<span style="color: black;">安排</span><span style="color: black;">制品</span>的重要入口。</span><span style="color: black;">与此<span style="color: black;">同期</span>,京ME<span style="color: black;">亦</span>为<span style="color: black;">咱们</span><span style="color: black;">供给</span>了<span style="color: black;">有些</span>必要的<span style="color: black;">加强</span><span style="color: black;">制品</span>体验的API,<span style="color: black;">例如</span>唤起手机拍照或相册、<span style="color: black;">是不是</span>是wifi环境、分享功能;京ME还<span style="color: black;">供给</span>自定义导航栏;<span style="color: black;">针对</span><span style="color: black;">制品</span>验证与发布,京ME还<span style="color: black;">供给</span>白名单测试及灰度发布。</span><span style="color: black;"><span style="color: black;">不外</span>在接入京ME中<span style="color: black;">亦</span>遇到了<span style="color: black;">有些</span>问题。<span style="color: black;">例如</span>分享功能,<span style="color: black;">能够</span>分享给私域之外的<span style="color: black;">地区</span>,如<span style="color: black;">微X</span><span style="color: black;">博客</span><span style="color: black;">伴侣</span>圈,而这些是<span style="color: black;">咱们</span>不需要的,关于定制化的分享功能,则需要像京ME提需;<span style="color: black;">一样</span>还是分享功能,云鸽分享链接,<span style="color: black;">由于</span>咚咚在处理链接时<span style="color: black;">显现</span>了正则匹配问题,<span style="color: black;">显现</span>了跨平台间<span style="color: black;">区别</span>的展示结果,<span style="color: black;">例如</span>同一个链接在安卓下打开失败,iOS下可用,而分享卡片的协议<span style="color: black;">转</span>,有时在iOS下不可用,而安卓OK。</span><span style="color: black;">在<span style="color: black;">研发</span>过程中,<span style="color: black;">因为</span>京Me接入只支持java服务端,暂时不支持nodejs服务端,再<span style="color: black;">认识</span>京Me服务端认证算法后,<span style="color: black;">咱们</span>同步在nodejs中做了实现,<span style="color: black;">同期</span>将<span style="color: black;">关联</span>功能封装为koa中间件&nbsp;@jd/koa-jdme-passport ,<span style="color: black;">详细</span><span style="color: black;">运用</span>可参考该中间件<span style="color: black;">运用</span>文档。</span><span style="color: black;">其间,京ME<span style="color: black;">制品</span>和<span style="color: black;">开发</span>小伙伴都鼎立<span style="color: black;">帮助</span><span style="color: black;">咱们</span><span style="color: black;">处理</span>问题,只是<span style="color: black;">最后</span>需要京ME发版,<span style="color: black;">咱们</span>需要过一段时间再发布分享功能。</span><span style="color: black;">7</span><strong style="color: blue;"><span style="color: black;">云鸽笔记的复盘总结</span></strong><span style="color: black;">经过这一段时间的紧凑型项目<span style="color: black;">研发</span>及<span style="color: black;">制品</span>体验的<span style="color: black;">提高</span>,<span style="color: black;">咱们</span>在项目中充分利用<span style="color: black;">分部</span>内部的工具资源,<span style="color: black;">包含</span>设计协作效率工具REALY平台(视觉稿一键标注),前端移动端UI组件库Yep-react,内部构建工具等;对<span style="color: black;">咱们</span>现有工具的实施与完善<span style="color: black;">亦</span>做了进一步的验证和优化<span style="color: black;">意见</span>。</span><span style="color: black;">最重要的是,<span style="color: black;">咱们</span>提出的<span style="color: black;">制品</span><span style="color: black;">方法</span>,填补了内部笔记管理及团队间协作的空白,给笔记<span style="color: black;">需要</span>的伙伴一个很好的平台,<span style="color: black;">亦</span>给需要文档协作的团队一个很好的<span style="color: black;">选取</span>。</span><span style="color: black;">最后,欢迎您随时<span style="color: black;">运用</span>云鸽笔记,有任何优化<span style="color: black;">意见</span>都<span style="color: black;">能够</span>提给<span style="color: black;">咱们</span>,<span style="color: black;">一块</span>打磨更<span style="color: black;">优秀</span>、有价值的笔记<span style="color: black;">制品</span>。</span>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><strong style="color: blue;"><span style="color: black;">京东数科技术说&amp;技术课堂</span></strong></strong></span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><span style="color: black;"> &nbsp; &nbsp;▼▼▼</span></span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">由京东数科-数字技术中心策划组织</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">倡导“原创·实用·技术·专业”</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">致力于分享技术<span style="color: black;">行业</span>实战经验与技术干货</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">线上订阅“京东数科技术说”,线下聆听“技术课堂”</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">为加强技术分享、总结沉淀,<span style="color: black;">提高</span>数科技术影响力而搭建的</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">线上线下融合交流平台</span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></span><span style="color: black;">不只一技之长 · 我有N技在手</span><span style="color: black;"><span style="color: black;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"></span></span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;">咨询、<span style="color: black;">意见</span>、合作请联系:</span></strong></span></p>
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;"><span style="color: black;">刘嘉璐(liujialu)/张明瑛(zhangmingying3)</span></strong></span></p><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;"><img src="data:image/svg+xml,%3C%3Fxml version=1.0 encoding=UTF-8%3F%3E%3Csvg width=1px height=1px viewBox=0 0 1 1 version=1.1 xmlns=http://www.w3.org/2000/svg xmlns:xlink=http://www.w3.org/1999/xlink%3E%3Ctitle%3E%3C/title%3E%3Cg stroke=none stroke-width=1 fill=none fill-rule=evenodd fill-opacity=0%3E%3Cg transform=translate(-249.000000, -126.000000) fill=%23FFFFFF%3E%3Crect x=249 y=126 width=1 height=1%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E" style="width: 50%; margin-bottom: 20px;">
    <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;"><strong style="color: blue;">长按识别二维码关注<span style="color: black;">咱们</span></strong></span></p>




页: [1]
查看完整版本: 云鸽笔记|技术复盘与总结