pwa重构东京大巴线路图,浅谈vue项目重构技术中央和小结

pwa重构东京大巴线路图

2018/03/28 · JavaScript
· PWA

原来的文章出处:
Neal   

在此以前一向有在保证三个香岛大巴线路图的 pwa,最重大的特色正是 “offline
first”。不过由于代码都以通过原生的 js
去落到实处,此前作者都不是很兴奋去用框架,不想拥有任何框架的偏好。可是到末代随着代码量的增多,代码的确变得混乱不堪,拓展新职能也变得更其困难。因而,花了接近四个礼拜的时候对于利用举行了一次完整的重构。网址访问地址:

前言

浅谈vue项目重构技术大旨和小结,vue技术要点

前言

近年来太忙了,博客好久未有立异了。前些天忙里偷闲,不难总计一下多年来vue项目重构的1些技艺中央。

vue数据更新, 视图未更新

以此标题大家日常会遇上,一般是vue数据赋值的时候,vue数据变化了,不过视图未有立异。那个不到底项目重构的技巧宗旨,也和豪门大饱眼福一下vue2.0普普通通的缓解方案吗!

缓解方案如下:

一、通过vue.set格局赋值

Vue.set(数据源, key, newValue)

2、 通过Array.prototype.splice方法

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

三、修改数据的尺寸

数据源.splice(newLength)

四、变异方法

Vue.js
包装了被考查数组的多变方法,故它们能触发视图更新。被打包的情势有:

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

prop 对象数组应用

在 JavaScript 中目的和数组是援引类型,指向同3个内部存款和储蓄器空间,借使 prop
是叁个指标或数组, 在子组件内部改变它会潜移默化父组件的图景
。利用这点,大家在子组件中改变prop数组或许目的,父组件以及全体应用到prop中数据的地方都会转变。作者在此以前写过一篇js深拷贝和浅拷贝的小说,感兴趣的去看下,其实,原理是1致的。

案例如下:

<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、定义3个有些变量,并用 prop 的值初步化它:

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

贰、定义一个计量属性,处理 prop 的值并再次回到:

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

v-model 的1部分坑

其实v-model和sync都以有的语法糖,小编在此以前有成文介绍过,官网也能找到类似的案例!

v-model
数据有时是undefined的时候,不会报错,所以,一定要留心,v-model无法是undefined,不然某些莫名的难点!

重构-动态组件的创导

突发性大家有为数不少类似的机件,只有一丝丝地点不雷同,大家得以把如此的类似组件写到配置文件中,动态创制和引用组件

方法①:component 和is同盟使用

透过利用保留的 成分,并对其 is
天性进行动态绑定,你能够在同3个挂载点动态切换八个零件:

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

措施2:通过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加载进来!

以上就是本文的整体内容,希望对我们的上学抱有援助,也愿意大家多多支持帮客之家。

前言
近期太忙了,博客好久未有更新了。今日忙里偷闲,简单计算一下以来vue项目重构的1…

准备

预备干活先做好,在 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
讯息。还有,大家还亟需获得每种站点的时刻表音讯,卫生间地点音讯,无障碍电梯消息以及出入口新闻。那里是写了有的爬虫去官网爬取并做了有的数量处理,再一次就不一1赘述。

近来太忙了,博客好久未有立异了。明日忙里偷闲,不难总计一下近年来vue项目重构的壹部分技能中央。

设计

数量准备好之后,就是运用的宏图了。首先,对组件举行三次拆分:

vue数据更新, 视图未更新

组件结构

将总体地图知道成二个 Map 组件,再将其分为 四 个小器件:

图片 1

  • Label: 地图上的文本音信,包含大巴站名,线路名称
  • Station: 大巴站点,包涵普通站点和转化站点
  • Line: 大巴线路
  • InfoCard:
    状态最复杂的一个零件,重要含有时刻表音讯、卫生间地方音讯、出入口消息、无障碍电梯音讯

那是2个大概的零件划分,里面只怕带有越多的其它成分,比如 InfoCard 就有
InfoCard => TimeSheet => 提姆esheetTable 那样的嵌套。

其一难点大家平常会碰着,一般是vue数据赋值的时候,vue数据变动了,然则视图未有创新。那么些不到底项目重构的技术宗旨,也和豪门分享一下vue二.0一般性的消除方案吗!

组件通讯和状态管理

地方开发的最大的困难应该便是那一块的剧情了。本来出于组件的层级并不算特别复杂,所以笔者并不打算上
Redux
那体系型的大局状态管理库。重要组件之间的通讯正是父亲和儿子通讯和兄弟组件通讯。父亲和儿子组件通讯比较不难,父组件的
state 即为子组件的
props,能够透过这几个完毕老爹和儿子组件通讯。兄弟组件略为复杂性,兄弟组件通过共享父组件的地方来开展通讯。假如这样的光景,小编点击站点,希望可以弹出音信提示窗,那就是Station 组件和 Info卡德 组件之间的通讯,通过 Map 组件来进展共享。点击
Station 组件触发事件,通过回调更新 Map 组件状态的换代,同时也促成了
InfoCard组件的更新。同时为了促成,点击任何区域就足以关闭音信提示窗,我们对 Map
组件实行监听,监听事件的冒泡来完毕快速的关闭,当然为了防止某个不须求的冒泡,还供给在壹部分事件处理中梗阻事件冒泡。

图片 2

InfoCard 是极端复杂的八个组件,因为内部含有了1些个
icon,以及气象音信的切换,同时必要贯彻切换不相同的站点的时候能够更新音讯提醒窗。要求专注消息提示窗新闻初次点击消息的早先化,以及切换区别icon
时分别显示不相同的新闻,比如卫生间音讯可能出入口消息,以及对此时刻表,切换不一样的路线的时候更新对应的时刻表。那些意况的转折,须求值得注意。此外值得壹题的点正是,在切换区别站点的时候的场地,假若笔者正在看有个别站点的换衣间音信的时候,小编点击其它多个站点,这时候弹出的新闻提示窗应该是时刻表音讯依旧卫生间音讯呢?小编的取舍依旧卫生间消息,作者对于这一气象实行了保持,那样的用户体验从逻辑上来讲仿佛更佳。具体完成的代码细节就不壹一表达了,里面肯能包括愈来愈多的底细,欢迎使用体验。

缓解方案如下:

性格优化

以上那些的支付得益于此前的爱抚,所以重构进度依旧相比较快的,稍微通晓了下
react 的用法就达成了重构。可是,在上线之后接纳 lighthouse
做分析,performan 的得分是 0 分。首屏渲染以及可互相得分都以 0
分,首先来分析一下。因为全部应用都以通过 js 来渲染,而最棒基本的便是可怜
svg。整个看下去,有几点值得注意:

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

找到难题点,就能够想到1些缓解方案了。第三个比较简单,压缩 json
数据,去除一些不供给的新闻。第二个,好的化解办法就是经过异步加载来完结组件加载,效果显明,越发是对于
InfoCard 组件:

一、通过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
多分,注解那样的创新要么比较可行的。别的2个值得说的点正是首屏,因为历史原因,整张图
svg 7月素的任务都以定死的,及横坐标和纵坐标都已经是概念好的,而 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的质量可以在1些运动装备上还足以应用 GPU 加快,并且 translateX
不会唤起页面包车型地铁重绘或许重排,只会造成图层重组,最小制止对质量的震慑。

2、 通过Array.prototype.splice方法

部署

时下的布局方案是运用 create-react-app 的法定提出,通过 gh-pages 达成将
build 的打包文件上传到 gh-pages 分支上从而完成布置。

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

兼容性

当下该利用在 Chrome 浏览器的支持性是最棒的,安卓浏览器建议设置 Chrome
浏览器选拔,小编一般也都对比欣赏在大哥伦比亚大学上使用谷歌(Google)浏览器。对于 Safari
浏览器,别的的浏览作用就如没有怎么大标题,近日应该还没帮助添加到主显示器。可是在此后的
ios 版本好像对于 pwa 有着更进一步的支撑。

三、修改数据的长度

结语

图片 4

花了三个礼拜的小时成功了类别的总体的重构,从这个时候来的 commit
记录能够见见7月份疯狂 commit
了1波,主假若率先个周四开支了两日的日子修改了诸多代码,被那一个 InfoCard的情状切换搞了很久,前面正是指向质量做了一些优化。进程很伤心,一度疑心本身的
coding 能力。可是最后照旧有以下感悟:

  • 世界上并未最佳的言语,最棒的框架,唯有最合适的
  • 最优雅的兑现都不是毫不费劲的,都以一个个试出来的

谈到底1个冷笑话:

青春问禅师:“请问大师,小编写的次序为啥没有取得预期的出口?”
禅师答到:“年轻人,那是因为你的程序只会按您怎么写的推行,不会按你怎么想的履行啊……”

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

 

1 赞 收藏
评论

图片 5

数据源.splice(newLength)

四、变异方法

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,控制台会发出警告!引用官方给出的缓解方案如下:

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

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

二、定义二个计算属性,处理 prop 的值并赶回:

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

v-model 的一部分坑

其实v-model和sync都以部分语法糖,作者以前有成文介绍过,官网也能找到类似的案例!

v-model
数据有时是undefined的时候,不会报错,所以,一定要专注,v-model不能是undefined,不然有个别莫名的难题!

重构-动态组件的创导

有时我们有众多类似的零部件,唯有一丝丝地点不一致,大家能够把这么的好像组件写到配置文件中,动态创制和引用组件

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

Post Author: admin

发表评论

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