pwa重构新加坡地铁线路图,浅谈vue项目重构技艺大旨和小结

pwa重构新加坡客车线路图

2018/03/28 · JavaScript
· PWA

原来的文章出处:
Neal   

事先平素有在维护一个新加坡大巴线路图的 pwa,最根本的天性就是 “offline
first”。不过由于代码都是由此原生的 js
去达成,以前自个儿都不是很爱怜去用框架,不想具有其余框架的偏幸。可是到前期随着代码量的加多,代码的确变得七零八落,扩充新职能也变得尤为困难。由此,花了接近四个礼拜的时候对于利用进行了三次完整的重构。网址访问地址:

前言

准备

预备职业先做好,在 vue 和 react 之间,小编或然选取了前者。基于
北京赛车app软件下载,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 个小零件:

北京赛车app软件下载 1

  • Label: 地图上的文书新闻,包涵客车站名,线路名称
  • Station: 地铁站点,富含普通站点和中间转播站点
  • Line: 地铁线路
  • Info卡德:
    状态最复杂的一个组件,主要包蕴时刻表消息、卫生间地方新闻、出入口新闻、无障碍电梯新闻

那是三个差不离的零部件划分,里面或然富含越多的别的成分,举个例子 InfoCard 就有
InfoCard => TimeSheet => TimesheetTable 那样的嵌套。

以此问题大家平日会境遇,经常是vue数据赋值的时候,vue数据变化了,可是视图未有立异。那一个不到底项目重构的技艺中央,也和豪门享用一下vue2.0平常的化解方案吧!

零件通讯和境况管理

地面开拓的最大的难题应该就是这一块的剧情了。本来出于组件的层级并不算特别复杂,所以本人并不准备上
Redux
那体系型的大局状态管理库。首要组件之间的通讯正是父亲和儿子通讯和兄弟组件通讯。父子组件通讯比较简单,父组件的
state 即为子组件的
props,能够经过这一个达成老爹和儿子组件通信。兄弟组件略为复杂性,兄弟组件通过分享父组件的意况来进行通讯。假若那样的情景,我点击站点,希望能够弹出新闻提示窗,那正是Station 组件和 InfoCard 组件之间的通讯,通过 Map 组件来进展分享。点击
Station 组件触发事件,通过回调更新 Map 组件状态的翻新,同期也贯彻了
InfoCard组件的换代。同期为了兑现,点击任何区域就足以关闭音讯提示窗,大家对 Map
组件举办监听,监听事件的冒泡来达成赶快的关闭,当然为了避免某些不需求的冒泡,还供给在生龙活虎部分事件管理中梗阻事件冒泡。

北京赛车app软件下载 2

InfoCard 是无比复杂的一个零部件,因为中间蕴含了少数个
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);
  }
}

北京赛车app软件下载 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、改革数据的长度

结语

北京赛车app软件下载 4

花了三个礼拜的流年成功了品种的完好的重构,从这年来的 commit
记录能够看来三月份发狂 commit
了一波,首假如率先个周六费用了两天的时日订正了成都百货上千代码,被特别 InfoCard的意况切换搞了非常久,后边就是指向质量做了一些优化。进程相当的惨恻,生机勃勃度猜忌自个儿的
coding 手艺。不过最后依旧有以下感悟:

  • 世界上从未有过最佳的言语,最棒的框架,只有最合适的
  • 最高雅的兑现都不是举手之劳的,都以叁个个试出来的

末尾多少个冷笑话:

青春问禅师:“请问大师,小编写的顺序为啥一向不赢得预期的输出?”
禅师答到:“年轻人,那是因为你的次第只会按您怎么写的进行,不会按您怎么想的奉行啊……”

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

 

1 赞 收藏
评论

北京赛车app软件下载 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基于百度地图组件重构笔记分享

发表评论

电子邮件地址不会被公开。 必填项已用*标注