自记录开发问题

思考问题思路记载

  • 是否字段填写错误
  • 官方组件是否正常引入,以及相对应的样式是否引入
  • 是否设置响应式
  • 逻辑是否正确
  • 数据是否正确加载
  • 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>
  1. 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)
    },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值