pwa重构上海地铁线路图,浅谈vue项目重构技术要

2019-10-07 05:06 来源:未知

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

InfoCard 是然则复杂的三个组件,因为中间满含了几许个 icon,以及气象新闻的切换,同期要求达成切换差异的站点的时候能够创新新闻提示窗。需求注意信息提示窗音讯初次点击消息的初叶化,以及切换不一样icon 时分别彰显差别的信息,比方卫生间消息仍旧出入口音讯,以及对此时刻表,切换不相同的路径的时候更新对应的时刻表。那些景况的转账,要求值得注意。其余值得一题的点就是,在切换分裂站点的时候的情况,假诺笔者正在看有个别站点的盥洗室音讯的时候,作者点击其余一个站点,那时候弹出的音信提醒窗应该是时刻表音信只怕卫生间音讯吗?小编的采纳还是卫生间音讯,作者对此本场地实行了维持,那样的客商体验从逻辑上来讲就像更佳。具体贯彻的代码细节就不一一表达了,里面肯能包涵越多的内部原因,招待使用体验。

杀鸡取蛋方案如下:

个性优化

上述这么些的耗费得益于从前的爱抚,所以重构进程或许非常快的,稍微熟习了下 react 的用法就产生了重构。可是,在上线之后选择 lighthouse 做深入分析,performan 的得分是 0 分。首屏渲染以及可互相得分都是 0 分,首先来深入分析一下。因为任何应用都以透过 js 来渲染,而特别核心的便是可怜 svg。整个看下来,有几点值得注意:

  • 代码直接将 json 导入,导致 js 容积过大
  • 怀有组件都在渲染的时候举办加载

找到标题点,就能够想到一些技术方案了。第1个比较轻易,压缩 json 数据,去除一些无需的音讯。第4个,好的消除办法正是经过异步加载来落到实处组件加载,效果鲜明,特别是对于 Info卡德 组件:

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基于百度地图组件重构笔记分享
TAG标签:
版权声明:本文由金沙澳门唯一官网发布于前端开发,转载请注明出处:pwa重构上海地铁线路图,浅谈vue项目重构技术要