项目中前端开辟题目经验总结
ie下websocket的平安限定题目
题目形貌:
数据看板中的数据大部分都是及时数据或前一天统计的历史数据,因而这边后端斟酌采纳websocket来及时和定时推送数据来保证数据的及时性和有效性。而前端开辟这边为了进步前端开辟的复用性,采纳了在各个组件中开辟成一个个的小部件,然后在流派经由过程vue异步动态加载的体式格局来完成,小部件的组装拼接。 因而在组件中开辟的小部件都是单vue页面。因而涌现了有几个小部件就有几个websocket,如今我这边就涌现了7个websocket。
题目征象:
在ie浏览器下,翻开时就会发明报错。IE控制台会报SecurityError毛病。
解决要领:
构成上述征象的原因是ie下websocket衔接做了平安限定,假如websocket衔接凌驾6个时,那末就会衔接失利。默许最大衔接数为6个。
那末怎样防止报错呢?
固然ie下的限定我们是不好修正的,假如真的强迫修正,那末能够经由过程修正注册表来修正最大衔接数(固然这边是不发起的,不能够让客户区修正浏览器注册表的)。
那末我们须要的就是防止多个websocket的衔接。
2个思绪:
运用websocket之前先思索,是不是真的有必要运用wesocket??
- 假如是及时推送,定时推送这些场景,那末完整没有必要运用websocket,前端可经由过程定时器来完成雷同的功用。因而能防止运用就防止运用。
- 假如是报警等未知的推送,那末我们就是必需要运用websocket的,而且假如恰好运用在了看板小部件上。那末照样会涌现7个websocket的状况。所以这类状况下就须要和后端沟通,一个项目采纳一个websocket效劳,经由过程type来辨别。那末看板就只要一个websocket了。然则如今看板的小部件都是自力,怎样去完成一个websocket?那末须要借助一下事宜通讯。以下:
a.vue
created () {
this.$root.eventBus = new Vue()
this.init()
},
methods: {
init (i) {
let ws = new WebSocket()
ws.onmessage = (data) => {
this.$root.eventBus.$emit('websocket', data)
}
}
}
b.vue
created () {
this.$root.eventBus.$on('websocket', () => {
// 处置惩罚推送的数据
})
}
我们晓得我们的小部件都是经由过程在流派,经由过程vue动态加载组件的体式格局来构成看板的,那末所以小部件就都会在流派这个vue实例对象下。所以能够采纳this.$root下挂在一个vue实例来完成事宜的通报
备注:
别的假如你一个页面中只要4个websocket,而以为ie下就不会报错,请不要这要处置惩罚,也请运用type的情势来处置惩罚。因为ie下革新页面烧毁websocket是时间延迟的。第一次进入页面websocket衔接是一般的,而舒心页面后,能够就会构成2个websocket衔接失利。
hui多言语运用题目
题目形貌:在运用hui控件的时刻,会涌现某些bug,然后bug修正后,项目中运用的hui版本也对应的晋级。然则这类状况下,能够会涌现hui内置多言语增添了一些字段,致使项目中会涌现有未翻译的字段。
解决要领:
- 在我们各个组件框架下的i18n下面有一个hui.js文件,这个文件内部就是hui的多言语,这个多言语版本是在脚手架完成的时刻就已建立了,它是不会跟着hui的晋级而变化,因而我们就须要从hui那里去拿到最新的包(node_modules/hui/lib/locale/lang/zh-CN.js),然后再替代更新。
- 固然我们除了手动如许替代以外,我们也能够直接援用这个文件,那末今后就不须要再替代了。(固然翻译的文件照样须要更具index.json来翻译最新的)
把hui.js替代成以下代码那末中文状况就能够跟着hui的晋级而变化了
hui.js
修正前:
let hui = {
colorpicker: {
confirm: '一定',
clear: '清空'
},
....等所以hui的key值
}
export default hui
修正后:
import hui from 'hui/lib/locale/lang/zh-CN.js'
export default hui.el // 这边是因为hui内部包了一层el,所以直接抛出hui.el的对象
多言语题目的拓展:
在组件中开辟中怎样运用多言语呢?之前组件开辟我都是把变量抛到表面,经由过程挪用者通报参数进来,那末表面一定都是已转过多言语的了,那末这类一定是没题目的,固然这不是迥殊好的。因而这边把hui-pro怎样运用多言语的体式格局来申明一下,今后开辟组件中碰到多言语题目都能够如许操纵,向hui那样把言语放到项目工程中。
首先在工程中须要建立对应的言语js文件如zh_CN.js
然后在建立一个挪用的体式格局:
import defaultLang from 'hui-pro/src/locale/lang/zh-CN';
import Vue from 'vue';
import deepmerge from 'deepmerge';
import Format from './format';
const format = Format(Vue);
let lang = defaultLang;
let merged = false;
let i18nHandler = function() {
const vuei18n = Object.getPrototypeOf(this || Vue).$t;
if (typeof vuei18n === 'function' && !!Vue.locale) {
if (!merged) {
merged = true;
Vue.locale(
Vue.config.lang,
deepmerge(lang, Vue.locale(Vue.config.lang) || {}, { clone: true })
);
}
return vuei18n.apply(this, arguments);
}
};
export const t = function(path, options) {
let value = i18nHandler.apply(this, arguments);
if (value !== null && value !== undefined) return value;
const array = path.split('.');
let current = lang;
for (let i = 0, j = array.length; i < j; i++) {
const property = array[i];
value = current[property];
if (i === j - 1) return format(value, options);
if (!value) return '';
current = value;
}
return '';
};
export const use = function(l) {
lang = l || lang;
};
export const i18n = function(fn) {
i18nHandler = fn || i18nHandler;
};
export default { use, t, i18n };
这个js文件是用于兼并工程中的多言语或本身翻译t函数就是对外组件运用多言语的要领。
这边经由过程做一个mixins
import { t } from 'hui-pro/src/locale';
export default {
methods: {
t(...args) {
return t.apply(this, args);
}
}
};
然后直接在组件中运用该mixins即可
<template>
{{ t(`h.common.add`) }}
</template>
import Locale from 'hui-pro/src/mixins/locale';
export default {
mixins: [Locale]
}
require的运用题目
题目形貌: 如今这边有那末一种场景,前端有一些列的都市的json文件,而前端须要依据后端的返回值来挪用响应的都市json文件。关于这类状况下:我就运用了require加载动态文件的体式格局来加载,因为require是同步加载的,所以比较轻易。运用体式格局以下
let city 从后端猎取
let cityMap = require(`static/city/${city}.json`);
// 后续依据cityMap再处置惩罚
就以上那末一段代码在打包的时刻会将city下的所以json文件都打包的js内里。(require是提早把一切的文件都打包进来,才使得能够动态的加载)。
构成了js比本来痴肥了许多。(痴肥水平是跟city下json文件大小有关)。然后进入对应的页面也会相对要慢一些(js比本来大了一些),如许用户体验不好。
因为关于动态加载的体式格局只管防止(假如文件小的话,那影响不大)
解决要领:
动态猎取的文件(这边的city.js,多言语,皮肤包等等)只管都经由过程ajax来猎取,如许打包的js文件会少许多。
为了保证还是同步的,那末就采纳es7的async、await来操纵吧
async get () {
let city = xxx
try {
let cityMap = await xxx.get('xxxx')
// 在依据cityMap出咯
} catch {}
}
流派看板小部件打包的一些题目
题目形貌:之前报告了一篇关于怎样打包小部件的,然则那篇并没有运用庞杂的页面,援用第三方插件等。就是纯真几个简朴的页面的测试。这一次现实打包今后发明依然有不少题目须要优化:
- 打包的文件会比较大。这是因为每一个单vue文件打包,将一切依靠都打包进来了,那末就构成文件过于痴肥,比拟于单vue实例的结果会差许多,会反复打包vue,hui,echarts等一些插件。
因而这边须要剔除依靠举行打包,要领以下:
// webpack设置中增添以下设置项,如另有其他第三方插件都能够设置在以下
externals: {
echarts: 'echarts',
hui: 'hui',
vue: 'vue'
},
经由过程以上过滤,能够讲一个文件从几M缩小到100KB之内。
- 小部件中没法猎取到本身组建内部的多言语。
a. 这个是因为小部件内部是经由过程this.$t的情势去挪用i18n来翻译的。可小部件的环境发生了变化,经由过程流派动态挪用组件的体式格局加载,那末小部件地点的环境就是流派的vue实例对象,那末i18n也就是流派的,所以小部件就没法获得翻译。
b. http的实例对象内部也不能够经由过程i18n以及{message} from ‘hui’这些。原因是已剔除了这些依靠,那末打包后就会报错,i18n和hui不存在。
解决要领: 经由过程一个设置文件内里寄存本身组件中的i18n的json文件途径(/oams/static/i18n/zh-CN/index.json),以及一个keys字段。将看板的部件多言语文件给让流派下载,并跟流派本身的多言语兼并(因而多言语key一定要加上本身的上下文或其他来和流派辨别,不要字段堆叠)。这些组件内部经由过程this.$t也都能一般翻译。
hui上传组件的题目
题目形貌: 如今前端都运用了一致的前端要求封装,http都做了一些处置惩罚如登录逾期跳上岸页,可上传组件是组件内部本身ajax要求,因而是不会做这些特别处置惩罚。因而在组件内部须要本身做一下
解决要领:
假如当前已登录逾期,那末后端单点登录针对Content-Type为application/json都是后端做了一层处置惩罚,返回errorCode为pleaseRefreshByHeader,那末前端依据这个值来跳登录页。然则上传组件的Content-Type:multipart/form-data,这类范例的单点登录是直接举行阻拦而不会经由后端,直接返回毛病页面。
那末我们就须要针对返回的页面做特别处置惩罚
uploadSuccess (res, file) {
if (res.code === '0') {
this.$message.success(this.$t(`oams_common.addSuccess`))
this.addMapDialog = false
this.$emit('add-map-success')
} else {
// 页面逾期处置惩罚
if (res.includes && res.includes('html')) {
let refreshUrl = '/isecure/cas/login?service=' + location.protocol + '//' + location.host + location.pathname
location.href = refreshUrl
} else {
// 毛病码处置惩罚
this.$message.error(this.$t(`oams_errorcode.${res.code}`))
this.$refs.mapUpload.clearFiles()
this.$nextTick(() => {
this.mapForm.filename = ''
})
}
}
}
除了上面的要领还能够在上传组件前,先本身发送一个接口考证当前页面是不是已逾期,假如已逾期,那末它就会自动跳转首页了(本身的接口都是经由处置惩罚的),而且这也不单单处置惩罚了单点登录,收集超时也做了响应了处置惩罚。(上传组件是没有做超时处置惩罚的,因为不晓得文件上传须要多久,假如设置了,收集差的状况下能够上传文件或图片就失利了)