思考问题思路记载
- 是否字段填写错误
- 官方组件是否正常引入,以及相对应的样式是否引入
- 是否设置响应式
- 逻辑是否正确
- 数据是否正确加载
- https//http是否兼容
- 数据是否存在并且判断是否存在安全机制
- 异步问题
- 数据以及dom渲染先后问题
- 父子组件通信问题
1.request.js
文件中接口进行拦截,如果不成功则返回 Promise.reject(new Error(${res.code}-${res.msg || res.message} || 'Error'))
无法根据返回的状态进行更改,此时使用promise.then(()=>{}).finally()
进行问题解决。
2.遍历object内容(error) Promise.reject
Reflect.ownKeys(obj).forEach(function(key){
console.log('key',key);
console.log('message',obj[key])
});
/*stack:useList.ts:27 message Error: 1026-xxxxxxx at xx.xx.xx.use.xx.xx(http://xx.xx.com/src/utils/xxx.ts?t=xx)
message:1026-当前查询时间内尚未上报报表数据*/
3.发生时间:2021/09/02
form表单校验返回,使用封装函数判断是否校验成功。
const valid = ()=>{
let res
formRef.value.validate((valid:boolean)=>{
valid ? (res = true) : (res = false);
})
return res
}
4.发生时间 2021/09/06
tips:upload文件点击预览图片未生效
<el-upload
:action="uploadAction"
:limit="1"
:with-credentials="true"
list-type="picture-card"
:before-upload="beforeUpload"
:on-preview="handlePictureCardPreview"
:on-success="successUpload"
:on-exceed="exceedUpload"
:file-list="fileList"
>
<i class="el-icon-plus" />
</el-upload>
<el-dialog v-model="dialogVisible" append-to-body="true">
<img style="width:100%;height:100%;display:center;" fit="contain" :src="dialogImageUrl" alt="">
</el-dialog>
#ts:
const handlePictureCardPreview = (file:any) =>{
dialogImageUrl.value = file.url
dialogVisible.value = true
}
4.发生时间2021/09/07
点击取消按钮,input表单内还是更改之后的数据
解决方式:使用JSON.stringfy()
const reset = ref<>()
#初始化
reset.value = JSON.stringify(storeArr.value)
#取消函数内
Data.value = JSON.parse(reset.value)
5.关于el-DateTimePicker 日期时间选择器时间限制问题
<el-form-item label="生效时间" prop="effectType">
<el-select v-model="formData.type" placeholder="请选择生效时间类型" @change="typeEdit">
<el-option v-for="item of type" :key="item.value" :value="item.value" :label="item.label" />
</el-select>
<el-date-picker v-if="formData.effectType==='type'" v-model="formData.startTime" type="datetime"
format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择生效时间" @change="changePicker"
:picker-options="pickerOptionsStart" />
</el-form-item>
<el-form-item label="失效时间" prop="endTime">
<el-date-picker v-model="formData.endTime" type="datetime" format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择失效时间" :disabled="this.formData.startTime?false:true"
:picker-options="pickerOptionsEnd" />
</el-form-item>
pickerOptionsStart: {
selectableRange: (() => {
let data = new Date();
let hour = data.getHours();
let minute = data.getMinutes();
let second = data.getSeconds();
return [`${hour}:${minute}:${second} - 23:59:59`]
})(),
disabledDate(time) {
var date = new Date();
date.setFullYear(date.getFullYear() + 2);
date.setDate(date.getDate() - 1);
return (time.getTime() < Date.now() - 8.64e7) || (time.getTime() > date.getTime());
}
},
pickerOptionsEnd: this.endDate(),
//失效时间约束
endDate() {
const self = this
return {
disabledDate(time) {
if (self.formData.effectStartTime) { //如果开始时间不为空,则结束时间大于开始时间
return new Date(self.formData.effectStartTime).getTime() > time.getTime()
} else {
return time.getTime() < Date.now()//开始时间不选时,结束时间最大值大于等于当天
}
}
}
},
6.脱敏信息处理
export const telFilter = (value:string)=>{
if (!value) return ''
value = value.toString()
// return value.charAt(0).toUpperCase() + value.slice(1)
return value.substring(0,3)+'****' + value.substring(value.length-4)
}
export const nameFilter = (value: string)=>{
if (!value) return ''
value = value.toString()
// return value.charAt(0).toUpperCase() + value.slice(1)
return value.substring(0,1)+'****'
}
export const idFilter = (value: string)=>{
if (!value) return ''
value = value.toString()
// return value.charAt(0).toUpperCase() + value.slice(1)
return value.replace(/(\w{3})\w*(\w{2})/,'$1****$2')
}
export const emailFilter = (value: string)=>{
if (!value) return ''
value = value.toString()
const index = value.indexOf('@')
return '****' + value.substring(index-1)
}
7.ElMessageBox弹窗需要不显示cancel和confirm按钮
ElMessageBox.alert('message', 'title',{showCancelButton:false,showConfirmButton:false})
/*(property) ElMessageBox.alert: (message: string, title: string, options?: ElMessageBoxOptions | undefined) => Promise<MessageBoxData> (+1 overload)*/
options选择写在后面的对象当中
链接:https://element-plus.gitee.io/zh-CN/component/message-box.html#options
8.异步处理过后prop对象中的v-model绑定的数值已经变化但是视图没有更新
function().then(res=>{
if(res){
this.$set(this.item, 'name', name)
}
})
当你发现你给对象加了一个属性,在控制台能打印出来,但是却没有更新到视图上时,也许这个时候就需要用到this. s e t ( ) , 来 解 决 这 个 问 题 t h i s . set(), 来解决这个问题this. set(),来解决这个问题this.set的功能就是解决这个问题的啦。官方解释:向响应式对象中添加一个属性,并确保这个新属性同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新属性,因为 Vue 无法探测普通的新增属性 (比如 this.myObject.newProperty = ‘hi’),你会发现vue官网是vue.set,vue.set的用法,给你们插入连接。
作者:梅花骨朵 链接:https://www.jianshu.com/p/6f28f5abee08
9.router的query中的参数没有及时更新
watch: {
// 监听路由发生改变
$route: {
handler(newVal) {
if (newVal.query.tenantCode) {
this.tenantCode = this.$route.query.tenantCode;
}
},
},
},
10.移动端页面hover属性没有生效,这是因为移动端不支持hover属性,增加hover属性需要点击才会显示。
11.white-space:nowrap对纯字母没有作用,依旧不换行,可以使用word-break:break-all来进行强制换行
div{
word-break: normal;
word-break: break-all;
word-break: keep-all;
}
/*word-break: normal ; 依照亚洲语言和非亚洲语言的文本规则,允许在字内换行break-all : 该行为与亚洲语言的normal相同。也允许非亚洲语言文本行的任意字内断开。该值适合包含一些非亚洲文本的亚洲文本keep-all : 与所有非亚洲语言的normal相同。对于中文,韩文,日文,不允许字断开。适合包含少量亚洲文本的非亚洲文本*/
(1)white-space 属性设置如何处理元素内的空白
white-space: normal|pre|nowrap|pre-wrap|pre-line|inherit;
normal默认。空白会被浏览器忽略。
pre 空白会被浏览器保留。其行为方式类似 HTML 中的 pre 标签。
nowrap文本不会换行,文本会在在同一行上继续,直到遇到 br 标签为止。
pre-wrap 保留空白符序列,但是正常地进行换行。
pre-line 合并空白符序列,但是保留换行符。
inherit 规定应该从父元素继承 white-space 属性的值。
(2)word-wrap 属性用来标明是否允许浏览器在单词内进行断句
word-wrap: normal|break-word;
word-wrap 属性用来标明是否允许浏览器在单词内进行断句
normal: 只在允许的断字点换行(浏览器保持默认处理)
break-word:在长单词或URL地址内部进行换行,
/内容将在边界内换行。如果需要,单词内部允许断行。/
(3)word-break 属性用来标明怎么样进行单词内的断句
word-break: normal|break-all|keep-all;
normal:使用浏览器默认的换行规则。
break-all:允许在单词内换行 , 允许任意非CJK(Chinese/Japanese/Korean)文本间的单词断行。
keep-all:只能在半角空格或连字符处换行,
不允许CJK(Chinese/Japanese/Korean)文本中的单词换行,只能在半角空格或连字符处换行。非CJK文本的行为实际上和normal一致。
12.vue 文字左右循环滑动
<template>
<div class="my-outbox">
<div class="my-inbox" ref='box'>
<div class="my-list" v-for="(item,index) in sendVal" :key='index' ref="list">
请关注
</div>
<!-- <div class="my-list" v-for="(item,index) in sendVal" :key='(index+1)*100'>
请关注
</div> -->
</div>
<div class="node" ref="node">请关注</div>
</div>
</template>
<script>
export default {
name:'my-marquee-left',
props:{
sendVal:Array
},
data() {
return {}
},
mounted:function(){
var that = this;
var target = this.$refs.box;
var initLeft = 0;
setInterval(function(){
initLeft ++;
// 如果偏移大于元素+右边距则重新开始
if(initLeft >= (that.$refs.node.offsetWidth+that.$refs.list.marginRight)){
initLeft = 0;
}
target.style = 'transform: translateX(-'+ initLeft +'px)';
},40)
}
}
</script>
<style lang="scss" scoped>
.my-outbox{
font-size: 28px;
color: #D7BC8D;
overflow: hidden;
height: 70px;
background: #422b02;
position: relative;
.my-inbox{
white-space: nowrap;
position: absolute;
font-size: 0;
.my-list{
margin-right: 25px;
display: inline-block;
font-size: 28px;
height: 35px;
line-height: 35px;
.my-uname{
color: #FF8900;
}
}
}
}
.node{
position: absolute;
z-index: -999;
top: -999999px;
width: auto;
font-size: 28px;
}
</style>
使用:
<template>
<div>
<marqueeLeft :send-val='send'></marqueeLeft >
</div>
</template>
<script>
import marqueeLeft from './marque/index.vue'
export default {
data:function(){
return{
send:[]
}
},
components:{ marqueeLeft },
}
</script>
- absolute定位元素会置于fixed元素上方,设置z-index即可
原因:
https://www.freesion.com/article/36971399107/
14.问题场景:
父组件调用dialog,倒计时未完成则点击取消,再次打开dialog,倒计时数字为上次关闭数字,进而倒计时变为负数。
解决方式:将setInterval作为全局变量
因为setInterval为异步函数,组件销毁时无法进行清理,需要手动进行处理,不然会一直存在,同时还会造成内存泄漏。
data() {
return {
timer: null// 定时器
}
},
// 点击取消
handleCancle() {
this.checkDialog = false
// 取消的时候清除定时器
clearInterval(this.timer)
},
// 倒计时
countDown() {
this.downTime = 5
this.checkDialog = true
this.timer = setInterval(() => {
--this.downTime
if (this.downTime <= 0) clearInterval(this.timer)
}, 1000)
},