您的位置:澳门新葡8455最新网站 > Web前端 > pwa重构新加坡客车线路图,浅谈vue项目重构本事

pwa重构新加坡客车线路图,浅谈vue项目重构本事

发布时间:2019-10-10 04:21编辑:Web前端浏览(99)

    pwa重构新加坡大巴线路图

    2018/03/28 · JavaScript · PWA

    初稿出处: Neal   

    此前一贯有在保安多少个北京大巴线路图的 pwa,最关键的性状就是 “offline first”。可是出于代码都以因此原生的 js 去落成,从前本人都不是异常的痛爱去用框架,不想有所任何框架的偏幸。然则到中期随着代码量的加码,代码的确变得混乱不堪,拓宽新职能也变得越来越困难。因而,花了贴近三个礼拜的时候对于利用进行了叁遍完整的重构。网址访谈地址:

    前言

    准备

    常备不懈干活先做好,在 vue 和 react 之间,小编或许选用了后面一个。基于 create-react-app 来搭建境况,crp 为你希图了二个开箱即用的开支条件,由此你不要求和煦亲手配置 webpack,因而你也无需形成一名 webpack 配置工程师了。

    另外一端,大家还索要有个别数目,蕴含站点音讯,线路门路,文字表明等等。基于从前的接纳,能够因而一小段的代码获取新闻。就此如要大家获取大家从前的站点在 svg 图中的相关属性,普通的站点使用 circle 成分,为了获得其属性:

    const circles = document.querySelectorAll('circle'); let result = []; circles.forEach(circle => { let ele = { cx: circle.cx, cy: circle.cy, sroke: circle.stroke, id: circle.id }; result.push(ele); }) const str = JSON.stringify(result);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const circles = document.querySelectorAll('circle');
    let result = [];
    circles.forEach(circle => {
      let ele = {
        cx: circle.cx,
        cy: circle.cy,
        sroke: circle.stroke,
        id: circle.id
      };
      result.push(ele);
    })
    const str = JSON.stringify(result);
     

    通过那样的代码大家就能够获取 svg 普通站点新闻,同理还可获得中间转播站音讯,线路路子新闻以至站点以至线路 label 音讯。还也是有,我们还要求获得每种站点的时刻表音信,卫生间地方音讯,无障碍电梯消息以至出入口音讯。这里是写了一些爬虫去官方网址爬取并做了部分数量管理,再度就不一一赘述。

    前段时间太忙了,博客好久未有更新了。前日忙里偷闲,轻易计算一下前段时间vue项目重构的某个技巧中央。

    设计

    数量计划好之后,正是行使的宏图了。首先,对组件进行一遍拆分:

    vue数据更新, 视图未更新

    组件结构

    将全方位地图知道成三个 Map 组件,再将其分成 4 个小组件:

    图片 1

    • Label: 地图上的文书新闻,富含大巴站名,线路名称
    • Station: 客车站点,满含常见站点和中间转播站点
    • Line: 客车线路
    • InfoCard: 状态最复杂的一个零部件,主要蕴含时刻表新闻、卫生间地点音信、出入口音信、无障碍电梯新闻

    这是贰个几乎的零部件划分,里面恐怕含有越多的其余成分,比方 InfoCard 就有 InfoCard => TimeSheet => TimesheetTable 那样的嵌套。

    以此难题大家平常会超过,日常是vue数据赋值的时候,vue数据变动了,不过视图未有更新。那些不到底项目重构的工夫宗旨,也和豪门大饱眼福一下vue2.0经常的建设方案吗!

    组件通信和情景管理

    本土开拓的最大的难处应该正是这一块的内容了。本来出于组件的层级并不算特别复杂,所以自个儿并不准备上 Redux 那连串型的大局状态管理库。主要组件之间的通信正是老爹和儿子通讯和兄弟组件通讯。老爹和儿子组件通讯相比轻易,父组件的 state 即为子组件的 props,能够透过那一个完成老爹和儿子组件通讯。兄弟组件略为复杂性,兄弟组件通过分享父组件的情景来进行通讯。若是那样的现象,小编点击站点,希望能够弹出新闻提示窗,那就是Station 组件和 InfoCard 组件之间的通讯,通过 Map 组件来扩丰富享。点击 Station 组件触发事件,通过回调更新 Map 组件状态的翻新,同期也落到实处了 InfoCard组件的革新。同期为了贯彻,点击任何区域就足以关闭音讯提示窗,大家对 Map 组件实行监听,监听事件的冒泡来达成急速的关闭,当然为了制止有些不供给的冒泡,还供给在局地事件管理中阻止事件冒泡。

    图片 2

    Info卡德 是最佳复杂的叁个组件,因为内部含有了一点个 icon,以至气象音信的切换,相同的时候须求贯彻切换差异的站点的时候能够立异音信提醒窗。要求小心新闻提醒窗音信初次点击消息的伊始化,乃至切换分裂icon 时分别呈现不一致的音讯,譬喻卫生间消息依旧出入口消息,以至对此时刻表,切换分化的路径的时候更新对应的时刻表。这么些景况的倒车,须要值得注意。别的值得一题的点便是,在切换分化站点的时候的意况,即使笔者正在看某些站点的茶水间新闻的时候,作者点击其余贰个站点,那时候弹出的音讯提示窗应该是时刻表音讯依旧卫生间新闻吗?作者的取舍依然卫生间消息,作者对此这一动静进行了维系,那样的客商体验从逻辑上来说就像是更佳。具体落到实处的代码细节就不一一表明了,里面肯能包含越多的内部原因,款待使用体验。

    缓慢解决方案如下:

    属性优化

    以上那一个的费用得益于在此以前的保证,所以重构进程仍然比异常的快的,稍微熟练了下 react 的用法就形成了重构。不过,在上线之后采纳 lighthouse 做深入分析,performan 的得分是 0 分。首屏渲染以致可互相得分都以 0 分,首先来深入分析一下。因为全体应用都以经过 js 来渲染,而最棒核心的正是老大 svg。整个看下来,有几点值得注意:

    • 代码直接将 json 导入,导致 js 容量过大
    • 具备组件都在渲染的时候进行加载

    找到问题点,就足以想到一些缓慢解决方案了。第二个比较轻松,压缩 json 数据,去除一些不须求的信息。第三个,好的消除办法便是透过异步加载来贯彻组件加载,效果明摆着,非常是对此 InfoCard 组件:

    1、通过vue.set情势赋值

    同步

    class InfoCard extends React.Component { constructor(props) {    super(props) { ...    }  }  ... }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class InfoCard extends React.Component {
      constructor(props) {
       super(props) {
        ...
       }
     }
     ...
    }
     
    Vue.set(数据源, key, newValue)
    

    异步

    export default function asyncInfoCard (importComp) { class InfoCard extends React.Component {    constructor(props) { super(props); this.state = { component: null }; } asyncComponentDidMount() { const { default: component } = await importComp(); this.setState({ component: component })    }  } }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    export default function asyncInfoCard (importComp) {
      class InfoCard extends React.Component {
       constructor(props) {
          super(props);
          this.state = {
            component: null
          };
        }
        
        asyncComponentDidMount() {
          const { default: component } = await importComp();
          this.setState({
            component: component
          })
       }
     }
    }
     

    与上述同类我们就贯彻了将一并组件改产生叁个异步加载的零部件,那样就没有要求一下子加载全体的机件。那样大家就足以在 Map 中央银行使异步的艺术来扩充零部件的加载:

    import asyncInfoCard from './InfoCard' const InfoCard = asyncInfoCard(() => import('./InfoCard')

    1
    2
    3
    import asyncInfoCard from './InfoCard'
    const InfoCard = asyncInfoCard(() => import('./InfoCard')
     

    透过上线之后的属性剖判,lighthouse 质量评分一下子就上升到了 80 多分,注解那样的革新要么相比实用的。别的三个值得一提的点就是首屏,因为历史原因,整张图 svg 兰月素的职责都以定死的,及横坐标和纵坐标都已然是概念好的,而 svg 被定为在中游。在活动端加载时,展现的正是右臂的空白区域,所以给顾客一种程序未加载实现的错觉。从前的本子的做法正是通过 scroll 来贯彻滚动条的滚动,将视图的刀口移动到中游地方。此次的主见是透过 transform 来实现:

    .svg { transform: translate(-100px, -300px) }

    1
    2
    3
    .svg {
    transform: translate(-100px, -300px)
    }

    诸有此类完结了总体 svg 图地点的摇动,使用 lighthouse 实行分析,品质分降到了 70 多分。继续思量有未有此外的秘籍,后来自家想在最左上上角定义一个箭头动画。

    img src="right_arrow.png" alt="right arrow" title="right arrow" class="right-arrow"/>

    1
    img src="right_arrow.png" alt="right arrow" title="right arrow" class="right-arrow"/>

    .right-arrow { animation: moveright 3s linear infinite; } @keyframs moveright { 0% { transform: translateX(2rem); } 50% { transform: translateX(3rem); } 100% { transform: translateX(5rem); } }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    .right-arrow {
      animation: moveright 3s linear infinite;
    }
    @keyframs moveright {
      0% {
        transform: translateX(2rem);
      }
      50% {
        transform: translateX(3rem);
      }
      100% {
        transform: translateX(5rem);
      }
    }

    图片 3

    那样大家就足以成立三个周而复始向右移动的卡通,提醒顾客向右滑动。安排之后察觉品质分立马降到 0,索性也就废弃了那个做法。最终来时间调节制动用 transform: translateX(-200px) translateY(-300px); ,因为那样经过 css3 的性子能够在一部分活动设备上仍是可以够利用 GPU 加快,何况 translateX 不会孳生页面包车型大巴重绘或许重排,只会导致图层重组,最小制止对性能的熏陶。

    2、 通过Array.prototype.splice方法

    部署

    当前的安排方案是接纳 create-react-app 的合法提议,通过 gh-pages 完结将 build 的打包文件上传到 gh-pages 分支上进而达成计划。

    数据源.splice(indexOfItem, 1, newValue)

    兼容性

    近些日子该行使在 Chrome 浏览器的帮忙性是最好的,安卓浏览器提出安装 Chrome 浏览器接纳,小编日常也都比较欣赏在三弟大上利用Google浏览器。对于 Safari 浏览器,别的的浏览作用如同从未什么样大难点,近日应当还没帮助增多到主显示屏。但是在后头的 ios 版本好像对于 pwa 有着更上一层楼的支撑。

    3、修改数据的长短

    结语

    图片 4

    花了八个礼拜的命宫成功了档案的次序的完好的重构,从那个时候来的 commit 记录能够见到七月份疯狂 commit 了一波,首假如率先个周天费用了二日的小时修改了好多代码,被百般 InfoCard的图景切换搞了十分久,前边便是指向质量做了一些优化。进度异常的惨烈,一度猜忌本人的 coding 技能。可是最终依然有以下感悟:

    • 世界上并没有最佳的言语,最佳的框架,独有最合适的
    • 最高贵的达成都不是一举成功的,都以二个个试出来的

    末段二个冷笑话:

    青年问禅师:“请问大师,我写的前后相继为啥没有获取预期的出口?” 禅师答到:“年轻人,那是因为你的次序只会按你怎么写的举办,不会按您怎么想的试行啊……”

    源代码地址,欢迎 star 或者 pr。

     

    1 赞 收藏 评论

    图片 5

    数据源.splice(newLength)

    4、变异方法

    Vue.js 包装了被考查数组的产生方法,故它们能触发视图更新。被包裹的不二等秘书诀有:

    push()
    pop()
    shift()
    unshift()
    splice()
    sort()
    reverse()
    

    prop 对象数组应用

    在 JavaScript 中指标和数组是援用类型,指向同四个内部存款和储蓄器空间,假如 prop 是贰个目的或数组, 在子组件内部退换它会影响父组件的景色。利用那或多或少,大家在子组件中退换prop数组恐怕指标,父组件以致所有应用到prop中多少的地点都会生成。我在此以前写过一篇js深拷贝和浅拷贝的稿子,感兴趣的去看下,其实,原理是一样的。

    案举个例子下:

    <input class="pinput max" type="text" v-model="itemData.data.did">
    
    <script>
    export default {
     components: {
     },
     data() {
     },
     props: {
     itemData: Object
     },
     methods: {
     }
    };
    </script>
    

    具有应用到itemData的地方都会生成!

    下边这种改换prop,Vue 不会在调节台给出警示,借使大家完全改变只怕赋值prop,调整台会发出警示!援用官方给出的缓和方案如下:

    1、定义三个局地变量,并用 prop 的值早先化它:

    props: ['initialCounter'],
    data: function () {
     return { counter: this.initialCounter }
    }
    

    2、定义叁个测算属性,管理 prop 的值并再次来到:

    props: ['size'],
    computed: {
     normalizedSize: function () {
     return this.size.trim().toLowerCase()
     }
    }
    

    v-model 的片段坑

    骨子里v-model和sync都以一些语法糖,作者前边有文章介绍过,官方网站也能找到类似的案例!

    v-model 数据有时是undefined的时候,不会报错,所以,必须要留神,v-model不可能是undefined,不然有个别莫名的主题材料!

    重构-动态组件的创设

    突发性大家有那个相近的机件,只有一丢丢地点不等同,我们得以把这么的近乎组件写到配置文件中,动态创设和援引组件

    艺术一:component 和is合作使用

    因此运用保留的 成分,并对其 is 特性实行动态绑定,你能够在同三个挂载点动态切换四个零部件:

    var vm = new Vue({
     el: '#example',
     data: {
     currentView: 'home'
     },
     components: {
     home: { /* ... */ },
     posts: { /* ... */ },
     archive: { /* ... */ }
     }
    })
    <component v-bind:is="currentView">
     <!-- 组件在 vm.currentview 变化时改变! -->
    </component>
    

    方法二:通过render方法创设

    <script>
    export default {
     data() {
     return {
     };
     },
     render: function(createElement) {
     let _type = bi.chart.data.type;
     let _attr = bi.chart.components[_type]["attr"];
     return createElement(_attr, {
      props: {
      }
     });
     }
    };
    </script>
    

    bi.chart.components[_type]["attr"]本条是在配置文件中动态配置的,type点击的时候会变动,会取区别type上面包车型大巴attr属性!

    公物性质抽离

    咱俩在类型中,日常会用非常多动静或然数额,大家得以把广大公共数据抽离出来,放到一个对象中,后边大家能够监听那么些数据对象变化。进行数量保存仍旧获得。

    c: {
     handler: function (val, oldVal) { /* ... */ },
     deep: true
    },
    // 该回调将会在侦听开始之后被立即调用
    d: {
     handler: function (val, oldVal) { /* ... */ },
     immediate: true
    },
    

    能够接纳方面深度监听。如若开首化的时候要立时实施,我们得以用当下实施监听!

    require动态加载正视

    笔者们能够选拔require同步性子,在代码中动态加载信赖,举个例子上边echart大旨,我们能够点击切换的时候,动态加载!

    require("echarts/theme/"+ data.theme);
    

    import加载要放置尾部,早先化的时候,能够把暗中同意宗旨用import加载进来!

    上述就是本文的全体内容,希望对咱们的就学抱有助于,也期望我们多多关照脚本之家。

    你可能感兴趣的稿子:

    • Map.vue基于百度地图组件重构笔记分享

    本文由澳门新葡8455最新网站发布于Web前端,转载请注明出处:pwa重构新加坡客车线路图,浅谈vue项目重构本事

    关键词:

上一篇:没有了

下一篇:没有了