前言
代码健壮性:
处理异常的代码.首要追求健壮性.
就是程序必须能从异常中自我恢复.由于代码多数时间跑的是"正常"逻辑,少数情况下才不得不处理"异常",所以"异常"处理的代码中,首要任务是健壮,跑不死,而高效性则是次要的.。
温故知新提示:书到用时方恨少,老司机高速你 收藏一份! 开发前用五到十分钟看一遍会避免很多bug的产生
一、对字段进行处理: 应该先进行判空 如果某个字段为null可能会导致整个页面不显示可以加个默认值如:
代码如下(示例):
// html中
span.text {{poptitle || ''}}
// js中
const params = {
string: this.str || '',
Number: this.num || null
// 设定默认值最好不要用undefined
}
params.字段 = canshu === 'accessPoint' ? '接入点位' : (canshu === 'alarmCount' ? '报警次数' : (canshu === 'resolveAlarm' ? '解决隐患' : '巡检次数'))
// 打点工具中
vkTrack.trigger('***', {
content_id: vobj.id + '',
content_title: vobj.activityType + '',
message: vobj.tagName || '',
parent_id: parentId,
content: '我'
})
2.因为没有监听到数据改变所以视图没有更新
代码如下(示例):
// 需要 this.$set()等方法添加强制刷新页面
template(slot="istime" slot-scope="scope")
el-date-picker(
v-model="scope.time"
type="datetimerange"
@change="changeTime"
:default-time="['00:00:00', '23:59:59']"
value-format="timestamp"
// 将中国标准时间转为时间戳
// 设置时间回显
this.$nextTick(() => {
this.$set(this.$refs.formInfo, 'time', nowTime)
this.$refs.formInfo.time = nowTime
})
3.实现小于12px的字体效果
// 重点在这 transform: scale(0.8) 这个代码片段不需要可以略过
.gift-bg
position: relative
background-color: #fff
box-shadow:0px 1px 11px 0px rgba(133,133,133,0.36)
pointer-events: none
&::after
position: absolute
bottom: 6px
left: 0
width: 57px
font-size: 12px
text-align: center
transform: scale(0.8)
animation: words 0.3s linear 0.5s both
content: '免费领取'
4.动态添加类名
<div v-bind:class="{ active: isActive }"></div>
5. 手写柱状图动画效果
mounted() {
// 先建立一个空数组 让柱状图初始值高度为0 延迟一秒以后将请求回来的数据用.fill(target, start, end) 赋值给list 动态添加高度 并且在状态切换的位置用v-if来判断
let data = new Array(this.reportProp.chartData.value.length)
data.fill(0)
this.list = data
this.$nextTick(() => {
setTimeout(() => {
this.list = this.reportProp.chartData.value
}, 1000)
})
思考: 你一定有更好的方法吧 评论发给我好不好呀
6.安装某个依赖安装不上 升级node版本
7. 垂直水平居中
allCenter()
position absolute
top 50%
left 50%
transform: translateX(-50%)
translateY(-50%)
思考: 开发中常用的方法或者组件可以问问看有没有公用的 没有可以自己建立一个
**8.**当阅读代码的时候发现这样的问题
methods: {
// 各种需要起名的地方也要注意常量用大写 起名有意义
getBusPrizeList () {
server.queryOption().then(res => {
if (res.code === 200 && res.data && res.data.sourceList) {
res.data.sourceList.forEach(item => {
// id 7是什么鬼 我要动它怎么办
if (item.id === 7) {
// 不想别人骂你的话 开发中魔鬼数字一定要增加注释
this.$set(this.$refs.formInfo, 'sourceId', item.name)
this.sourceListId = item.id
}})}})}}
思考:魔鬼数字主要影响了代码可读性,读者看到的数字无法理解其含义,从而难以理解程序的意图。当程序中出现的魔鬼数字过多时,代码的可维护性将会急剧下降,代码变得难以修改,并容易引发错误或线上问题。
9. + 号的使用你还记得吗?
可以将字符串转为数字类型 代码可以略过
html
// 此处用于复现不转化出现的bug
template(slot="signTimes" slot-scope="{ row, $index }")
el-input(v-model="row.signTimes" type="number" min=1 step=1 @blur="signTimeBlur(row, $index)" placeholder="请填写累签次数")
js
signTimeBlur (row, index) {
const days = this.nodeTime > 0 ? this.nodeTime : this.dayTime
if (+row.signTimes > days) {
//+row.signTimes可以将row.signTimes转为数字类型
this.$message.error('累计签到天数不得大于' + days + '天')
row.signTimes = ''
return
} else if (+row.signTimes <= 0) {
this.$message.error('累计签到天数不得小于1')
row.signTimes = ''
}
this.generalRuleList.forEach((item, i) => {
if ((index !== i) && +item.signTimes === +row.signTimes) {
this.$message.error('累签天数不可重复')
row.signTimes = ''
}
})
}
思考:你会的东西很多,但是有想过哪个是最简单易懂并且利于性能优化的吗
10. 来个手写的时间处理函数吧 确定不收藏吗?
const H = 3600000
const M = 60000
export default {
filters: {
// 时间戳转 至 YYYY-MM-DD HH:MM:SS
mixinFilterTimeTag2Format (value) {
if (!value) {
return '-'
}
if (typeof value === 'string') {
value = parseInt(value, 10)
}
if (typeof value === 'number') {
const time = new Date(value)
const format = {
year: time.getFullYear(),
month: time.getMonth() + 1,
date: time.getDate(),
hours: time.getHours(),
minutes: time.getMinutes(),
seconds: time.getSeconds()
}
for (const key in format) {
if (format[key] < 10) format[key] = '0' + format[key]
}
return `${format.year}-${format.month}-${format.date} ${format.hours}:${format.minutes}:${format.seconds}`
} else {
return 'NO TIME'
}
},
// 时间戳 至 YYYY-MM-DD 周X
mixinFilterTimeTag2FormatWithDay (value) {
if (!value) {
return '-'
}
if (typeof value === 'string') {
value = parseInt(value, 10)
}
if (typeof value === 'number') {
const time = new Date(value)
const format = {
year: time.getFullYear(),
month: time.getMonth() + 1,
date: time.getDate()
}
for (const key in format) {
if (format[key] < 10) format[key] = '0' + format[key]
}
const day = ['日', '一', '二', '三', '四', '五', '六'][time.getDay()]
return `${format.year}-${format.month}-${format.date} 周${day}`
} else {
return 'NO TIME'
}
},
// 计算时间:**小时*分钟
mixinTimeHourMinutes (value) {
if (!value) return '-'
const timerh = Math.floor(value / H)
const timerm = Math.ceil((value - H * timerh) / M)
if (timerh > 0 && timerm > 0) return `${timerh}小时${timerm}分钟`
if (timerh > 0 && timerm === 0) return `${timerh}小时`
if (timerh === 0 && timerm > 0) return `${timerm}分钟`
}
}
}
思考:公司应该有js代码库可以问一下 没有正好加一下,持续更新建议收藏
11. 使用filter加上文的时间处理函数完成时间转化与展示
template(slot-scope='scope')
el-form(label-position='left', inline)
el-form-item.div(label='创建人')
span {{ scope.row.createBy }}
el-form-item.div(label='创建时间')
span {{ scope.row.createTime | mixinFilterTimeTag2Format }}
el-table-column(label='活动结束时间', sortable="custom",width='140',prop="end_time")
template(slot-scope='scope')
span {{ scope.row.endTime | mixinFilterTimeTag2Format }}
el-table-column(label='更新时间', sortable="custom",width='100',prop="update_time")
template(slot-scope='scope')
span {{ scope.row.updateTime | mixinFilterTimeTag2Format }}
12. 有没有写过垃圾代码
if (params.cpReferralPrizeList.length === 0) { return this.form.prizeId += ''}
// 可以简化为
if (!params.cpReferralPrizeList.length) {
// 可以用es6语法
return ${this.form.prizeId}}
思考: 学过的es6 你有经常用吗 该回顾了
13. 项目中遇到一些场景,只能输入正整数,而且不能携带小数点,例如年龄,物品数量、ID等。el-input只允许输入正整数的校验
<el-input v-model.number="input" class="input-view" placeholder="请输入内容" oninput="value=value.replace(/[^0-9]/g,'')" />
// v-model.number 自动转为数字类型
// οninput="value=value.replace(/[^0-9]/g,'')" 通过正则表达式,限制只能为正数,切不能带小数点
14.文字和单词要考虑到超出是否隐藏或者换行
15.接口401导致频繁跳登陆页 可能接口未配置网关 也可能账号有问题 并非当前环境对应的账号密码 导致登陆不上去
16..替换链接的时候要注意参数是否有变化 携带参数进入页面是否正常 能不能用到 报不报错
17. p标签下的奇数行与偶数行
- p:nth-child(odd){} //奇数行
- p:nth-child(even){} //偶数行
- :last-child最后一个子元素
- :nth-child(n) 选择器匹配属于其父元素的第 N 个子元素,不论元素的类型。
- 强制不换行 : white-space:nowrap;
- display: inline-flex 父元素大小由子元素撑起来
div span:nth-children(3){}选择第三个span
div span:nth-children(-n-2){}选择前面两个
18.适配问题 考虑到内容撑不开盒子大小的时候加个最小高度不然屏幕留白会很丑
19. 随机生成id:$item.id + Math.random().toString(36).split(’.’)[1]
20. select 多选、远程搜索都有,参考官方示例。
如果el-option是v-for循环出来的,需要指定key,并且key值具有唯一性,不能使用index,会出问题。
如果想保留搜索结果,加reserve-keyword属性,(多选且可搜索时,是否在选中一个选项后保留当前的搜索关键词)。
21. key值为index导致删除功能出问题:
数组的key值,尽量不要用index,尤其是有删除功能的时候,这样会出问题:
index是区分数组里的每一个子元素的,用index作为key值,在删除的时候,比如删除了第一项,但是后续index改变,为0的是其它子元素(导致删除的可能是第二个子元素),(就是说index随着数组长度改变而改变,不像id之类的不会随之改变)
22. 对于按钮设置为router-link包裹的,按钮禁用**,router-link也不允许要跳转的话,设置pointer-events:none
它的作用是阻止用户的点击产生任何效果。
router-link(:class=“{ ‘stopclick’: ‘变量’/scope.row.status === 1 }”)
23. 相同select切换,value展示相同值,v-if的坑
问题描述:相同select下拉框,不同条件下展示,v-if可能会出现,切换另一个,把之前下拉框值带过去的情况,目前是:一个单选框,切换到多选框会出现当前问题。
问题根源:
v-if默认会对组件进行复用,因此如果有相同的组件,他会优先去选择相同的组件来显示,而很明显我们这里的组件是要区分开的,因此这里使用key来解决,可以将组件区分开。
解决问题:
1、 使用v-show.这样不会出现该展示问题,但是带来了校验问题,保存时候也校验了不展示的字段,多个form表单情况下会更加麻烦;
2、加key值。form-item加上一个key值,用于区分两个下拉框,可完美解决
24. 代码优化 - 重置内容
formInfo初始化可以单独提出来,用方法返回一个对象,后面数据重置的时候,直接调用初始化方法就可以。
formInfo:this.resetFormInfo()
resetFormInfo() {
const formInfo = { xx:xx }
return formInfo
}
重置时候:this.formInfo = this.resetFormInfo()
25.
指定js文件不进行exLink检查,可以使用/* eslink-disable */亲测可用!添加.exlinkignore文件可能不管用!
26.
template里的非空判断,可以使用filter过滤器进行处理。它的作用本身就是处理数据的。
27.
记录vue路由返回上一页方式。
针对vue-router:
1.this.
r
o
u
t
e
r
.
g
o
(
−
1
)
2.
t
h
i
s
.
router.go(-1) 2.this.
router.go(−1)2.this.router.back(-1)
针对浏览器:1.window.history.go(-1)(在vue里不建议使用,有bug:在hash模式下,有的浏览器对于hash变更不认为是两个不同的页面,所以不会返回,可以在js中使用)
2.window.history.back() 返回上一页
3.window.location.go(-1)刷新上一页
window.loacation.reload() 刷新当前页
28. 删除子元素,但是保留序列号,做法:
全局定义int,默认为1,数组初始化时候,给个属性,比如num,赋值为int。(或者直接为1也行)
每次push时候,int都加1,this.int += 1.
push时候,再次赋值num属性为int.就保留了每次添加时候的序列号了。
29. git报错 报错显示,git的一个swp后缀名文件已经存在导致的报错,简单快速解决方案是删除该交换文件:rm .git/.COMMIT_EDITMSG.swp
参考链接:http://www.voidcn.com/article/p-nhueqgyz-bwh.html
参考链接:https://blog.csdn.net/qq_32452623/article/details/78395832
30. 定义路由上的值:changePath (value) {
const obj = this.$route.query // 获取参数对象
this. $router.push({ path: this. $route.path, query: { …obj, channelKeyword: value } })
}
31. Vue动态加载本地图片时,有两种方式:
1.将图片作为模块导入进去,images:[{src:require(‘./1.png’)},这样webpack就能解析;
2.将图片写成绝对路径,如images:[{src:”/static/1.png”},可以通过在webpack.base.config.js定义来缩短路径的书写长度。
32. input输入框在IOS手机上,由于placeholder字体小于输入框字体,导致placeholder字体偏上显示。
解决方案:placeholder属性,设置line-height: normal; padding-top: 0.4rem(2px)。就可以。
类似支付宝还花呗-提前还款页面。input输入框问题。
input::-webkit-input-placeholder
padding-top .4rem
line-height normal
注意:父级元素不要设置diaplay: flex属性。更不要设置align-items为baseline,显示会出问题
总结
看完了有没有深思和自己的总结?
举个例子==
栗子1:
el-form-item.class_name(label="看下面:", prop="reminderTime" v-if="model.obj.id")
//
在模版上使用model.obj.id
可能取不到报错,导致模板解析失败,比如model.obj === undefiend model.obj.id就会thorw new Error()
栗子2:
params.reminderTime = (params.reminderTime === null || (params.reminderTime[0] === null && params.reminderTime[1] === null)) ? [] : params.reminderTime
// 有可能是undefined么? 其实直接判断真假就好避免报错
//以下是优化后
params.reminderTime = (!params.reminderTime || (!params.reminderTime?.[0] && !params.reminderTime?.[1])) ? [] : params.reminderTime
栗子3: 连续的三目运算操作可能写的时候方便,但是看的时候会不清晰,建议多条件操作的时候使用switch
return serviceType === 1 ? '0元领课' : serviceType === 2 ? '付费售卖' : '拼团'
// 以下是优化后的整体代码可以略过主要实现方式就是使用了switch进行判断
function serviceTypeSwitch (serviceType) {
switch (serviceType) {
case 1:
return '就'
case 2:
return '是'
case 3:
return '我咯'
}
}
export const getTableConfig = [
{
label: '场景',
prop: 'serviceType',
align: 'center',
customRender: (serviceType, value) => {
return serviceTypeSwitch(serviceType)
}
}, {
label: '展示渠道',
prop: 'groupType',
align: 'center',
// 简单的使用三木运算符
customRender: (groupType, value) => {
return groupType === 1 ? 'H5' : '小程序'
}
}
]
**整理不易 希望多多点赞互动或者关注一下,不然用的时候你确定你可以立刻找到吗? 新人小白可以看看我的另一篇文章~爱你**