写在前面,博主是个在北京打拼的码农,从事前端工作5年了,做过十多个大大小小不同类型的项目,最近心血来潮在这儿写点东西,欢迎大家多多指教。
目录
关于日常开发中遇到的那些~~~
一、划过显示二维码
二、关于打包时候为什么要分包的个人理解
三、git命令合并分支代码
四、翻转对象的方法
使用 Object.fromEntries 将数组转成对象
Object.fromEntries() 方法把键值对列表转换为一个对象
五、项目性能优化
1、开启gzip压缩代码
2、分包
六、关于 BuildAdmin使用中的问题
七、前端请求接口excel文件并下载
本文关键字:字符串键返回自动变成了数字
我们打包的文件每次更新其中的代码,打包后的文件识别到代码更新会修改相关文件的hash值,来进行热更新等,而我们如果把所有代码打包成一个文件,那么当我们只是修改了一行代码,整个文件都会重新加载,分包后只需要更新那行代码所在的文件就行了,所以分包后应用性能上有了提升
原文
我们都知道数组翻转方法reverse();那么怎么翻转对象呢
使用 Object.fromEntries 将数组转成对象
Object.fromEntries() 方法把键值对列表转换为一个对象
var obj={'1键':1,'2键':1};
const arr=Object.entries(obj);//转成数组[{'1键',1},{'2键',1}]
//翻转
const reverseArr = arr.reverse();
var finallyObj=Object.fromEntries(reverseArr);
注意注意,如果你的键是数字,某些浏览器会自动排序(相关文章),应该让后端把键转成字符串避免排序出错问题,否则每次都得前端做数据处理;
因为前端如果使用reverseArr.map(item=>[item[0]+'',item[1]],你会发现确实键都变成了字符串,但你使用Object.fromEntries(reverseArr.map(item=>[item[0]+'',item[1]])时会发现键又变成了数字
如果全数字组成的字符串不行,就应该这样就可以Object.fromEntries(reverseArr.map(item=>[item[0]+'随意字母',item[1]])
再给大家提供一个合并对象方法
console.log('{...{1:1,2:2},3:3} :>> ', {...{1:1,2:2},3:3});
spa这种单页应用,首屏由于一次性加载所有资源,所有首屏加载速度很慢。解决这个问题非常有效的手段之一就是前后端开启gizp(其他还有缓存、路由懒加载等等)。gizp其实就是帮我们减少文件体积,能压缩到30%左右,即100k的文件gizp后大约只有30k。
vue-cli初始化的项目中,是默认有此配置的,只需要开启即可
不分包:
每次都得重新下载更新后的文件
首屏的渲染速度变慢;
当搭建的应用注重用户打开速度时,合理的分包策略有助于减少用户首屏加载应用时加载的资源数量,并且对于部分资源可以复用,避免重复加载,从而提升用户体验。
拆出了common公共库,这个库主要是node_modules中的公共库,更新频率低,其它页面chunk都可以公用这块库,因此其它页面都只包含自己业务代码
对于一些不需要立即使用的组件,我们可以单独对它们进行拆分,拆分成一些小的代码块chunk.js;
这些chunk.js会在需要时从服务器加载下来,并且运行代码,显示对应的内容;
app.js文件中,是我们自己编写的所有代码逻辑。
chunk-vendors.js中是第三方的包(vuejs,vue-router,axios) 。
简单来说分包就是在webpack配置中,对entry入口配置多增加一些入口文件,然后配置output出口文件为动态名字,之后通过webpack的plugin把公共的代码chunk块都提取识别出来(可以通过hash名称捕获到具体文件),放入一个公共的bundle包文件里,就可以实现分包
当我们使用table组件时传入要渲染的内容
userColumn: [
{
title: '用户ID',
key: 'id',
width: 100,
align:'center',
fixed:'left'
},
{
title: '账号/手机号',
key: 'username',
width: 300,
align:'center',
render: (h, params) => {
return h('span',this.$comJs.getTel(params.row.username));
}
},
{
title: '声音锁',
key: 'isSoundLock',
width: 100,
align:'center',
render: (h, params) => {
if(params.row.isSoundLock == 1){
return h('span','已开启');
}else{
return h('span','未开启');
}
}
},
{
title: '小鹅通',
key: 'isXiaoeTong',
width: 100,
align:'center',
render: (h, params) => {
if(params.row.xiaoeTechId){
return h('span','已同步');
}else{
return h('span','未同步');
}
}
},
{
title: '姓名',
key: 'name',
width: 100,
align:'center'
},
{
title: '账户类型',
key: 'orgTypeName',
width: 100,
align:'center'
},
{
title: '会员类型',
key: 'flag',
width: 100,
align:'center',
render: (h, params) => {
if(params.row.flag==0){
return h('span','普通会员');
}else if(params.row.flag==1){
return h('span','svip会员');
}else{
return h('span','vip会员');
}
}
},
{
title: '推荐数据',
key: 'total',
width: 100,
align:'center',
render: (h, params) => {
return h('div', [
h('span', {
props: {
type: 'primary',
size: 'small'
},
style: {
color: '#3478f6',
cursor:'pointer'
},
on: {
click: () => {
if(params.row.total){
this.openTotal(params.row);
}else{
this.$Message.success('该用户暂无推荐数据!')
}
}
},
}, (params.row.total))
])
}
},
{
title: '用户类型',
key: 'regType',
width: 100,
align:'center',
render: (h, params) => {
if(params.row.regType==2){
return h('span','游客用户');
}else{
return h('span','普通用户');
}
}
},
{
title: '单位',
key: 'orgInfo',
width: 100,
align:'center'
},
{
title: '行业',
key: 'industryName',
width: 100,
align:'center'
},
{
title:'地区',
key:'operDtails',
width: 100,
align:'center'
},
{
title:'所属渠道商',
key:'distributorName',
width: 100,
align:'center',
},
{
title: '注册时间',
key: 'cTime',
width: 200,
align:'center'
},
{
title: '最后登录时间',
key: 'loginTime',
width: 200,
align:'center'
},
{
title: '操作',
key: 'action',
width: 620,
align: 'center',
fixed:'right',
render: (h, params) => {
return h('div', [
h('Button', {
props: {
// type: params.row.loginSource==3?'ghost':'primary',
type:'primary',
size: 'small'
},
style: {
marginRight: '5px'
},
on: {
click: () => {
// if(params.row.isPushTo==0){
this.SYPUSH(params.row)
// }else if(params.row.isPushTo==1) {
// this.SYPUSH(params.row)
// }
}
}
},(this.$comJs.getPermissions('USER_M_UPGRADE')?((params.row.loginSource==3)?'已推送声誉系统':'推送声誉系统'):'')) ,
h('Button', {
props: {
type: params.row.isPushTo==0?'primary':'ghost',
size: 'small'
},
style: {
marginRight: '5px'
},
on: {
click: () => {
if(params.row.isPushTo==0){
this.DataSide(params.row)
}else if(params.row.isPushTo==1) {
this.DataSide(params.row)
}
}
}
},(this.$comJs.getPermissions('USER_M_UPGRADE')?((params.row.isPushTo==0)?'添加数据终端':'已添加数据终端'):'')) ,
h('Button', {
props: {
type: params.row.isTable==0?'primary':'ghost',
size: 'small'
},
style: {
marginRight: '5px'
},
on: {
click: () => {
if(params.row.isTable==0){
this.Upgrade(params.row)
}
}
}
},(this.$comJs.getPermissions('USER_M_UPGRADE')?((params.row.gId==0)?'添加舆情服务':'已添加舆情服务'):'')) ,
h('Button', {
props: {
type: 'primary',
size: 'small'
},
style: {
marginRight: '5px'
},
on: {
click: () => {
this.sysUserInfor(params.row.id,params.row.username);
}
},
}, (this.sessionStrong.getPersession().indexOf('USER_AUTH_E')!=-1||this.sessionStrong.getPersession().indexOf('ADMIN')!=-1)?'用户详情':''),
h('Button', {
props: {
type: params.row.isFollow==0?'primary':'ghost',
size: 'small'
},
style: {
marginRight: '5px'
},
on: {
click: () => {
this.follow(params.row,params.index)
}
}
}, (params.row.isFollow==0)?'关注':'取消关注'),
h('Button', {
props: {
type: 'primary',
size: 'small'
},
style: {
marginRight: '5px'
},
on: {
click: () => {
this.href(params.index)
}
}
}, (this.sessionStrong.getPersession().indexOf('USER_M_P')!=-1||this.sessionStrong.getPersession().indexOf('ADMIN')!=-1)?'查看监测方案':''),
h('Button', {
props: {
type: 'primary',
size: 'small'
},
style: {
marginRight: '5px'
},
on: {
click: () => {
this.joinblack(params.row)
}
}
}, (this.sessionStrong.getPersession().indexOf('USER_M_P')!=-1||this.sessionStrong.getPersession().indexOf('ADMIN')!=-1)?'加入黑名单':""),
((!params.row.isAuthCom|| !params.row.isAuthPerson)&&(this.sessionStrong.getPersession().indexOf('USER_M_P')!=-1||this.sessionStrong.getPersession().indexOf('ADMIN')!=-1))?h('Button', {
props: {
type: 'primary',
size: 'small'
},
style: {
marginRight: '5px',
marginTop: '5px',
},
// 按钮是否显示,请返回布尔值
on: {
click: () => {
this.nowEditItemId=params.row.id;
this.$refs.person.valueObj={};
this.$refs.firm.valueObj={};
this.$refs.person.searchOverList=[];
this.$refs.firm.searchOverList=[];
this.childCompanyName='';
if(!params.row.isAuthPerson){
this.openPopup=true;
}else{
this.openFirmPopup =true;
}
}
},
}, ((!params.row.isAuthCom|| !params.row.isAuthPerson)&&(this.sessionStrong.getPersession().indexOf('USER_M_P')!=-1||this.sessionStrong.getPersession().indexOf('ADMIN')!=-1))?'添加声誉服务':''):'',
]);
}
}
],
当我们要渲染操作按钮
操作按钮中我们使用了vue的h自定义渲染内容函数
可有的时候我们要判断是否显示该渲染内容,针对h函数我们要怎么去控制显示隐藏,我在这里是使用三元判断运算符
(this.sessionStrong.getPersession().indexOf('USER_M_P')!=-1||this.sessionStrong.getPersession().indexOf('ADMIN')!=-1)?'加入黑名单':""),
((!params.row.isAuthCom|| !params.row.isAuthPerson)&&(this.sessionStrong.getPersession().indexOf('USER_M_P')!=-1||this.sessionStrong.getPersession().indexOf('ADMIN')!=-1))?h('Button', {
props: {
type: 'primary',
size: 'small'
},
style: {
marginRight: '5px',
marginTop: '5px',
},
// 按钮是否显示,请返回布尔值
on: {
click: () => {
this.nowEditItemId=params.row.id;
this.$refs.person.valueObj={};
this.$refs.firm.valueObj={};
this.$refs.person.searchOverList=[];
this.$refs.firm.searchOverList=[];
this.childCompanyName='';
if(!params.row.isAuthPerson){
this.openPopup=true;
}else{
this.openFirmPopup =true;
}
}
},
}, '添加声誉服务'):'',
核心是通过a标签去触发blob文件下载,用的是a标签的download方法
batchExport() {
if (!this.checkedIds.length) return this.$message.warning("请勾选数据");
this.$http({
method: "GET",
url: "/cbrc/user_center/department/export",
responseType: "blob",
params: {
ids: this.checkedIds.join(","),
},
}).then((res) => {
if (res) {
this.downloadFile(res);
}
});
},
downloadFile(res) {
let url = window.URL.createObjectURL(
new Blob([res.data], { type: res.headers["content-type"] })
);
let a = document.createElement("a");
a.style.display = "none";
a.href = url;
a.setAttribute("download", `导出数据.xls`);
document.body.appendChild(a);
a.click();
url = window.URL.revokeObjectURL(url);
document.body.removeChild(a);
},
文章传送门:大屏开发教学