工作中出现的问题总结(css,js,vue)

315 阅读7分钟

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

css相关

  1. 中英文在一个p标签里,如果要换行,会将整个英文部分换行,可以将换行改为,遇到任何字符就换行,加css属性:word-break = break-all;

  2. 单行省略:

    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    

    多行省略:

    overflow : hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;	
    
  3. 父元素flex:1,想要内部元素超出省略,又不想定宽,可以给父元素设置 min-width:0

    .right-desc
         flex 1
         min-width 0
         .title
           font-size 16px
           font-weight bold
           margin-bottom 10px
           ellipsis()
         .desc
           font-size 14px
           margin-bottom 10px
           ellipsis()
    
  4. css属性:

    • flex-shrink 当指定viewflex布局后,给子元素定义width是不起效果的。这个flex-shrink设置为1时,表示所有子元素大家同时缩小来适应总宽度。当flex-shrink设置为0时,表示大家都不缩小适应。所以,倘若给父元素设置了flex布局后,若要其子元素的width有效果,必须给子元素设置flex-shrink为0。
    • object-fit:cover 裁剪以适应内容框,不会失真。
  5. 上不动,下滚动这种布局,首先,

    1. 整个body,html,#app的高度要是屏幕的高度,这个 可以在app.vue里面设置,其他组件中设置无效,切记!
    2. 最外层布局设置flex 1 ;flex-direction:column;
    3. 上面不动的地方定高,下面flex:1
    4. 现在最主要的就是让下面的滚动起来,直接内部元素超出滚动就好了,overflow:auto

js相关

  1. 在一个函数中,使用forEach()循环,在循环里面写return语句,可能退出不了外层函数,可以将forEach()循环改为for()循环代替,可解决。

  2. 字符串的str.substr(),字符串的substr方法,参数1:起始位置,参数2:截取个数。

  3. 利用结构可以给属性赋值为默认值,就不用了再判断是否存在再给空值了,

    代码优化: 源代码:

    _this.fieldData = {
                apply_company_name: res.data.company_name? res.data.company_name: '',
                apply_user_name: res.data.apply_user_name? res.data.apply_user_name: '',
                apply_user_mobile: res.data.apply_user_mobile? res.data.apply_user_mobile: '',
                id_card: res.data.id_card? res.data.id_card: '',
                remark: res.data.remark? res.data.remark: ''
       }
    

    一阶段优化:

        const {
                company_name ,
                apply_user_name ,
                apply_user_mobile ,
                id_card ,
                remark
          } = res.data
          
          _this.fieldData = {
            company_name : company_name || '',
            apply_user_name: apply_user_name || '',
            apply_user_mobile: apply_user_mobile || '',
            id_card: id_card || '',
            remark: remark || ''
          }
          // 这里有个缺陷就是 company_name=0的时候,也会默认赋值为''
    

    二阶段优化:

            const {
                company_name = '',
                apply_user_name = '',
                apply_user_mobile = '',
                id_card = '',
                remark = ''
              } = res.data
              
              _this.fieldData = {
                company_name,
                apply_user_name,
                apply_user_mobile,
                id_card,
                remark
              }
    
  4. button按钮,默认是会提交表单的,不会执行button内的点击事件,有两种方案:1. 在button中,加上类型: type="button",2. 给form加上:阻止表单默认提交代码

  5. 使用数组的扩展运算符,如果这个数组不存在,为null 或者undefined

    会报错:In order to be iterable, non-array objects must have a [Symbol.iterator]() method.

    解决方案:给这个数组加个默认值

    // 原代码
    this.countryList = [...res.data.goods_lable_list]
    // 当goods_lable_list不存在为undefined或者null的时候,会报错
    // 可以用lodash()给数组加默认值为[]
    this.countryList = [..._.get(res,'data.goods_lable_list',[])]
    

Vue相关

  1. 项目中需要做一个从当前位置点击到商品详情页,返回的时候还是在原来的位置上,比如我的index.vue需要跳转到shopdetail.vue上,但是又不能设置用keep-alive标签包裹index.vue,所以用以下方法可解决。
  • index.vue中,离开页面时,将页面中的滚动条到顶部的距离存下来。因为每离开一次,就会存一次,所以不要清除操作。

    beforeRouteLeave(to, from, next){
      let position = window.scrollY()
      // 获取滚动条到顶部的距离
      this.$store.commit('SAVE_POSITION', position) //离开路由时把位置存起来
    
  • updated 或者 beforeUpdate 钩子都可以

    updated(){
      this.$nextTick(function(){
        let position = this.$store.state.scroolTop
        window.scroll(0,position)
      })
    },
    

    目前理解的是:由于<keep-alive>没有包裹组件,所以里面的钩子函数都会执行,但是为什么要放在updated里面?updated是数据一更新就会执行,所以存在的问题就是,tab切换数据的时候,也会执行updated,所以,切换tab的时候,即使没有离开页面,每次都会返回到首页顶部位置(因为默认值为0),所以解决方案如下:(在vue中,用window.scrollTo来滚动)

    返回离开页面时的位置最好的处理方式:

    1. 刚开始是一样的,都要记录离开首页时的位置
    2. 为什么离开之后,返回的位置都是一致的,而在控制台强行跳转起作用,原因是:返回的时候,数据还未完全更新,对于异步数据还没拿到的情况,都可以用延时器来处理,虽然处理起来的方式有点粗糙(加个300ms的时间)再去滚动距离。
    // 在你的接口请求函数里
      async getRecommendGoods () {
        try {
          const data =  await this.$http.get(`/goods_recommend?pageIndex=1&pageSize=5`)
          if (data.code === 0) {
            this.goods_click_list = data.data.goods_click_list
            this.goods_recommend_list = data.data.goods_recommend_list
            this.goods_salenum_list = data.data.goods_salenum_list
            this.$nextTick(()=>{
               setTimeout(()=>{
                window.scrollTo(0,this.$store.state.scroolTop) 
               },300)
             })
          }
        } catch (error) {
          console.log(error)
        }
      },
    
  • 一样的情况,通过异步请求的数据的结果来看数据

    // 正式用户或者游客             
              if(this.$tool.GetQueryValue('ssoTicket')){            
                 let timer = setInterval(()=>{
                        if(this.$store.state.userStatus !==''){                                          // 请求结果返回来了,清除定时器
                          window.clearInterval(timer)
                          timer = null; 
                          if(!timer){
                            if(this.$store.state.userStatus == 1){
                              // 正式用户                             
                            history.replaceState({},'title',url_game)
                            return window.location.href = this.$store.state.duibaGameUrl + "&" + this.$store.state.urlParam ;                        
                            }else {
                            history.replaceState({},'title',this.$tool.funcUrlDel('playgame')) 
                            history.pushState({},'title',url_game)
                            
                            return window.location.href = this.$store.state.duibaNotGameUrl + "&uid=not_login";
                            }
                         }
                        }
                  },100)  
              }
    
  1. 在项目中使用@和使用./引用文件的区别
    import Vue from './web-runtime'
    import { warn, cached } from 'core/util/index'
    import { query } from 'web/util/index’
    

./表示引用文件,引入某个不带./或者@的文件,表示import某个模块,直接去那个模块下去找。无非就是运行是的依赖引入路径 和打包引入文件路径 俩个路径,其中的@来省略路径,在webpack.base.conf.js 文件中去配置。

  1. js查找数组中是否存在某个值
    • some方法:找到某一项,就停止,返回值为false或者true
  2. 用vue控制样式,以对象的形式 :style={width:xx/xx*100+'%'}
  3. (快速原型开发)查看某个项目文件并运行看效果,调试代码,可将本文件改成名为App.vue,把文件需要的数据用import导入,在相关文件中,用export default导出.在终端vue serve运行本文件

解决better-scroll导致点击事件失效的原因和解决方法

better-scroll会默认阻止浏览器的原生点击事件,将属性值,click:true,才会派发一个click事件。要结合tap:true一起来使用。

在Vue中使用lodash中的节流函数

正确用法: click是个方法。

import _ from 'lodash'
export default{
    methods:{
        click:_.throttle(function(){
            console.log('hello')
            console.log(this)
        },1000)
    }
}

Set数据结构来去重

  • 2021-12-06 今天开发有个需求,是购物车下单,不同的网点不能提交数据,所以,问题来了,怎么判断有多个网点?源数据是一个数组里面包含了多个对象,类似于下面这种:
// 检查购物车订单是否包含不同网点,arr是一个数组,里面包含多个对象,对象里面某个字段是网点id。
    checkSelfSite (arr) {
      let siteArr = new Set()
      arr.forEach(e => {
      // 网点id !== ''的时候,才放到siteArr里面。
      if (_.get(e, ['selfNetInfo', 'orgCode'], '') !== '') {
          siteArr.add(e.selfNetInfo.orgCode)
        }
      })
      return siteArr.size > 1 //包含不同网点
    }
  },

扩展

用set方法可以给数组去重

function dedupe(array) {
  return Array.from(new Set(array));
}
dedupe([1, 1, 2, 3]) // [1, 2, 3]

try..catch...finally

无论try..catch...返回值是啥,finally里面的返回值说了算,finally块无论是否抛出异常都会执行。在项目中登录模块就运用到了,不管是否登录成功,或者这块代码有什么报错,都会执行finally那块代码。

切换网页

今天遇到个问题,前端网页一直有进度条,这个问题,第一种思路是:

  1. js代码执行中遇到报错,导致进程堵塞,但是这种,我的猜想是这种会立马报出错误,而不会让你自己去等待。
  2. 网络资源未加载完成 后面在页面多等了一会,资源请求失败,进度条就没了。 出现的问题就是:网页未加载完成,当前url不会放到浏览器历史栈中,等资源加载完成,就可以进行下一步操作了,比如返回之类的。

超柜进去订单详情页面进不去,其他渠道都ok

问题描述

前几个月做了一个复制订单号的功能,直接用的vue的插件,copy-text-to-clipboard.完美上线了几个月,这次发现超柜渠道进不去了。

解决思路:

  1. 先操作,再打开控制台。发现页面都进不去,chunk.js文件报错,看了一下应该是进了某一个catch(),后面就一顿爆红。

  2. 把这个chunk.js文件copy下来查看,发现进了这个copy指令的catch部分。

    1.png

  3. 查了一下,这个命令正好是前段时间做的复制功能,估计插件不适用,兼容性问题。

  4. 这部分可能要自己重写。重写也不复杂。

总结

就是要有一个解决问题的思路,页面都进不去。

思考:进某一个页面,应该首先进去这个页面的js文件,肯定是这个js文件报错了。至于怎么根据js文件来渲染页面,这个目前我这边还没研究过,等我慢慢学习吧~

最后

这个是平时工作中出现的问题及对应的解决思路,希望自己持续更新,加油坚持。