但是由于代码都是通过原生的 js,但是视图没有
分类:前端科技

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 => 提姆esheetTable 那样的嵌套。

以此主题材料大家平日会越过,常常是vue数据赋值的时候,vue数据变化了,然而视图未有更新。那个不算是项目重构的技艺中央,也和我们大饱眼福一下vue2.0平凡的化解方案吧!

零件通讯和状态管理

本土开荒的最大的难处应该正是这一块的剧情了。本来出于组件的层级并不算极度复杂,所以小编并不盘算上 Redux 那体系型的大局状态处理库。首要组件之间的通信就是老爹和儿子通讯和兄弟组件通信。父子组件通讯相比较轻巧,父组件的 state 即为子组件的 props,能够透过这一个完毕老爹和儿子组件通讯。兄弟组件略为复杂性,兄弟组件通过分享父组件的景色来举办通讯。若是那样的情状,作者点击站点,希望能够弹出新闻提示窗,那正是Station 组件和 InfoCard 组件之间的通讯,通过 Map 组件来张开分享。点击 Station 组件触发事件,通过回调更新 Map 组件状态的翻新,同一时间也落到实处了 Info卡德组件的立异。同不时候为了兑现,点击任何区域就足以关闭新闻提示窗,大家对 Map 组件举行监听,监听事件的冒泡来实现高效的关闭,当然为了幸免有个别不要求的冒泡,还索要在某事件处理中梗阻事件冒泡。

图片 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);
  }
}

图片 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基于百度地图组件重构笔记分享

本文由网上正规真人赌钱网站发布于前端科技,转载请注明出处:但是由于代码都是通过原生的 js,但是视图没有

上一篇:没有了 下一篇:indexedDB 基本使用
猜你喜欢
热门排行
精彩图文