常见错误与总结

1.object is not defiend

(1)可能事件名和name名冲突

(2)vuex方法辅组函数名写错

2. cli3.0静态文件要放在public下面才能读取

3.请求参数如果是写在请求体里面的要通过下面这个请求

QQ图片20190816113816.png

如果传入的参数是包裹在对象下键的话需要使用下面的方法进行传参

例如:

Object {payType: 0, batchNo: "18l5hja4qyx74", stopLosePrice: 17.155, stopWinPrice: 17.46} "first"

安装引入qs依赖

export const updateNewOrderStopPrice = (params) => {
  const data = qs.stringify(params)
  // console.log(data, 'databased')
  return ajax.request({
    url: '/order/newOrder/updateNewOrderStopPrice.do',
    method: 'post',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    data
  })
}
Z(}Z}5@{{1PLR48$8AK68J3.png

4.设置字体之间间距

letter-spacing: 8px

5.改变页面数据返回得图片大小

  for(let i in document.querySelectorAll('img')){
      if(typeof document.querySelectorAll('img')[i] == 'object'){
        document.querySelectorAll('img')[i].style.width = '94vw'
        document.querySelectorAll('img')[i].style.paddingRight = '2.7vw'
      }
    }

6.如果加载数据打印出来是个空数组展开之后才有数据,证明取值得时候数据还没有渲染出来,此时需要加个定时器,等拿到数据之后才做下一步操作

7.更改循环渲染的数据中的图片大小

  setTimeout(()=> {
      let imgList = document.getElementsByClassName("firstContent")
      // 类数组
      let a = Array.from(imgList)
      a.forEach((item) => {
        console.log()
        if(item.querySelector('a')){
          item.querySelector('a').querySelector('img').setAttribute('style','width: 86.5vw;height: 20vw;')
        }
      })
    },2000)

7.Class与Style动态绑定

1.对象语法

class
<div :class="{ active: isActive, 'text-danger' : hasError}"></div>
data: {
    isActive: true,
    hasError: false
}
style
<div :style="{color: activeColor,fontSize: fontSize + 'px'}">
    
</div>
data: {
    activeColor: 'red',
    fontSize: 30
}

2.数组语法

class
<div :class="[isActive ? activeClass : '', errorClass]">
    
</div>
data: {
    activeClass: 'active',
    errorClass: 'text-danger'
}

style

<div :style="[styleColor, styleSize]">
    
</div>
data: {
    styleColor: {
        color: 'red'
    },
    styleSize: {
        fontSize: '23px'
    }
}

8.使用vant中List懒加载,父子组件传参

list每次到达页面底部会触发一次onLoad事件加载数据,此时$emit一个事件告诉父组件加载下一页数据
 <van-list
      v-model="loading"
      :finished="isfinished"
      @load="onLoad"
    >
    <div
      class="content"
      v-for="(item,index) in BillItemData"
      :key="index"
      >
        <div class="center">
          <div class="right">
            <span class="title">{{item.remark}}</span>
            <span v-if="item.money" :class="['num',item.typeDetail>=0 ?'red':'green']">
              {{item.typeDetail>=0?'+':'-'}}{{item.money}}¥
            </span>
            <span v-else :class="['num',item.typeDetail>=0 ?'red':'green']">
              {{item.typeDetail>=0?'+':'-'}}{{item.score}}分
            </span>
          </div>
          <span class="time">{{item.createTime}}</span>
      </div>
    </div>
 </van-list>
export default {
  props: ['BillItemData','type', 'isLoading','isfinished'],
  data(){
    return {
      loading: false,
      finished: false,
    }
  },
  watch: {
    isLoading: function() {
      this.loading = false
    },
 
  },
  methods: {
    onLoad() {
      console.log('onload')
      this.$emit('toTheEnd',{
        type: this.$props.type,
        childLoading: this.loading
      })
    }
  }
}
父组件中使用子组件并监听toTheEnd方法,只要子组件触发toTheEnd方法就执行handleAddMore方法加载数据
传cashAlldone给子组件,表示数据加载完成,不需要再加载
<van-tabs class="font" v-model="active" color="#333" line-height="0.3vw" line-width="34.4vw" title-active-color="#333" title-inactive-color="#666">

    <van-tab title="现金明细">
      <div class="bond">
        <span class="money">{{remain.margin}}</span>
        <span class="sub">元(冻结保证金)</span>
      </div>

      <BillItem :BillItemData="cashList" @toTheEnd="handleAddMore" :isLoading="isLoading" type="money" :isfinished="cashAlldone"></BillItem>

      <p class="tc" v-show="this.cashAlldone">- 现金明细,全部加载完了 -</p>
    </van-tab>
 export default {
  components: {
    BillItem
  },
  data() {
    return {
      remain: {},
      active: '0',
      isLoading: '',
      cashList: [],
      cashPage: 0,
      scorePage: 0,
      pageSize: 10,
      scoreList: [],
      scoreAlldone: false,
      cashAlldone: false
    }
  },
  created () {
    this.loadBalance(),
    this.getDatas(
      this.$http.getCashDetail,
      { type: 'money'},
      this.pageSize,
      this.cashPage,
      'cashList'
    ),
    this.getDatas(
      this.$http.getCashDetail,
      { type: 'score'},
      this.pageSize,
      this.scoreList,
      'scoreList'
    )
  },
  methods: {
    handleAddMore(childData) {
      if(childData.type == 'money') {
        this.cashPage += 1;
        this.getDatas(
          this.$http.getCashDetail,
          childData,
          this.pageSize,
          this.cashPage,
          'cashList'
        )
      }
      if(childData.type == 'score') {
        this.scorePage += 1;
        this.getDatas(
          this.$http.getCashDetail,
          childData,
          this.pageSize,
          this.scorePage,
          'scoreList'
        )
      }
    
    },
    
      // 封装的方法
    getDatas(getDatasFn,childData, pageSizeType, pageType, whichList){
      if(getDatasFn) {
        getDatasFn({
          type: childData.type,
          offset: pageSizeType * pageType,
          size: pageSizeType
        }).then(resp => {
         // 当数据加载到最后的时候再次加载data就为0,如果data为0表示加载完成,此时this.cashAlldone = true
            
          if(resp.length == 0){
            if(childData.type == 'money'){
              this.cashAlldone = true
            } else if(childData.type == 'score'){
              this.scoreAlldone = true
            }
          }
          if(this[whichList]) {
              this[whichList] = this[whichList].concat(resp)
          } else {
            this[whichList] = resp
          }
          if(childData.childLoading != undefined) {
            this.isLoading = new Date()
          }
        })
      }
    },

    loadBalance() {
      this.$http.getBalance().then(resp => {
        if(resp) {
          this.remain = resp
        } else {
          this.$router.push({
            path: '/detailed'
          })
        }
      })
    }
  }
}

9.节流,当一个请求持续不断刷新的时候,要确保上一次请求已经返回,才做下一次请求

data: {
    return: {
        isPending: false
    }
},
  mounted () {
   this.timer = setInterval(() => {
       if(this.isPending === false){
       this.isPending = true
       this.getRankQuotaVariety();
       }
     },1000)
   },
  beforeDestroy () {
       clearInterval(this.timer);
  },
methods: {
    getRankQuotaVariety(){
     Promise.all([
        this.$http.getHomeData(), 
        this.$http.getTypeVariety()  
      ]).then((values)=> {
        this.isPending = false
         ……………………
     }
}

10.Content Editable

html中任何元素都可以编辑,通过js事件处理,可以将网页转换为完整且快速的富文本编辑器
<div contenteditable="true">
    This text can be edited by the user
</div>

11.如果数据是动态渲染的不论是字符串还是变量一定要加v-bind或:绑定,不然渲染不出来

12.循环渲染数据特别是父组件传参给子组件渲染的时候一定要分清楚是不是多次渲染了同一个东西

 <div class="international" v-if="active===0" >
    <SharesRisingModel :SharesDatas="quotationDisplay['外盘']"></SharesRisingModel>              
    <Sort :sortDatas="allTypeDatas['外盘']"></Sort>
        </div>   

13.把多维数组转换为一维数组values[1]下面包含三个数组

this.arrayTwo = [].concat.apply([], values[1])

14.两个数组通过对比某个字段是否相同,相同的话就糅合在一起

 this.arrayOne.forEach(item => {
      this.allDatas = this.isTypeAssign(this.arrayTwo, "varietyType", item)
 })
isTypeAssign(arr, type, parentItem) {
    arr.map((curr, index) => {
        if (parentItem.varietyType == curr.varietyType) {
            arr[index] = Object.assign({}, arr[index], parentItem);
        }
    })
    return arr
  },

15.报错方法“item”未在实例上定义,但在呈现期间引用。 通过初始化属性,确保此属性在数据选项或基于类的组件中是被动的。

可能是把标签元素嵌套层级写错了,比如里面的div中写的循环渲染,但是在div外面用v-if="item"判断了item是否有,此时嵌套层级出现问题,item不存在

16.实现组件复用时再次调用生命周期钩子函数

例如从/user/foo/user/bar原来的组件实例会被复用,不过这也意味这组件的生命周期钩子不会再被调用

方法一:可以使用wathch来监听$route的变化

方法二:可以在router-view上加一个唯一的key,来保证路由切换时都会重新渲染触发钩子函数

<router-view :key="key"></router-view>
computed: {
    key() {
        return this.$route.name !== undefined ? this.$route.name ++ new Date() : this.$route ++ new Date()
    }
    key() {
        return this.$route.fullPath
    }
}

16.登录和权限验证原理

  1. **登录:当用户填完账号信息和密码后向服务器验证是否正确,验证通过后,服务器会返回一个token,拿到token之后,将token存储到cookie中,保证刷新页面后能记住用户登录状态,前端会根据token再去拉去userinfo的接口来获取用户信息(如用户权限,用户名等)*****
  2. 权限验证:通过token获取对应的role,动态根据用户的role算出对应的权限路由,通过router.addRoutes动态挂载路由
  3. 用户登录成功之后,会在全局钩子router.beforeEach中拦截路由,判断是否已获得token在获得token之后既可以去获取用户的基本信息

17.如何覆盖UI组件默认样式

例如element-ui样式,由于element-ui样式是在全局引入的,所以想在某个view里面覆盖它的样式就不能加scoped,但是又想只是覆盖这个页面的element样式,就可以在他的父级加上一个class,用来命名空间来解决问题

.tag-wrap{ //你的命名空间
    .el-tag { //element-ui 元素
      margin-right: 0px;
    }
}

18.函数名千万不能和别的名字写重,否则会发现意想不到的错误,而且很难找出错误点

19.vant组件库中input有封装好的方法,怎么一直获取输入框焦点,使用ref获取实例,在点击按钮弹出dialog框的时候,让input框获取焦点

// 按钮上绑定的方法,触发方法的时候input框获取焦点
handleGetValidateCode() {
      // 获取验证码
      if (this.isCartdownStart === false) {
        const phoneReg = /^1[3456789]\d{9}$/;
        if (phoneReg.test(this.inputPhone)) {
          this.$http
            .getValidateCode({
              userPhone: this.inputPhone,
              regImageCode: ""
            })
            .then(resp => {
              // 600说明图片验证码错误
              // 601需要输入验证码
              if (resp.code == 601) {
                this.validateCodeIsShow = true;
                this.$http
                  .getValidateCodeImg({
                    userPhone: this.inputPhone
                  })
                  .then(resp => {
                    this.$refs.imgCodeInput.focus();
                    this.regImg = resp;
                  });
              }
            });
        } else {
          Toast("请输入正确的手机号");
        }
      }
    }

20.ajax轮询

ajax轮询分为两种:
  • 第一种:

设定一个定时器,无论有无结果返回,时间一到就会继续发送请求,这种轮询耗费资源,也不一定能得到想要的数据,这种轮询不推荐

  • 第二种:

在第一次请求的时候,如果返回数据了那么就在成功的回调里再次发起这个请求,就像递归一样,调用本方法,如果时间太久失败了,同样的再次调用这个请求,长轮询也需要后台配合,没有数据改变的时候就不用返回,或者约定好逻辑。

21.timeout.close is not a function

使用clearInterval过程中,IDE自动加上以下语句:

import { clearInterval } from "timers";

导致错误,直接删除

22.自定义svg插入图片不能使用require引入,直接在代码中写

<dl @click="toQuota">
   <dt>
      <!-- 不能这样用 -->
     <!-- <img :src="require('@/assets/image/ic_futures information@2x.png')" alt=""> -->
      <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
        <image xlink:href="../../assets/image/ic_futures information@2x.png" x="0" y="0" height="100" width="100" />    
      </svg>
   </dt>
   <dd>期货快讯</dd>
 </dl>

23.keep-alive include和exclude无效问题

使用include/exclude 属性需要给所有vue类的name赋值(注意不是给route的name赋值),否则 include/exclude不生效


export default {
 name:'a', // include 或 exclude所使用的name
 data () {
 return{
    }
  }
}

<keep-alive include="test-keep-alive">
  <!-- 将缓存name为test-keep-alive的组件 -->
  <component></component>
</keep-alive>

24.手动滑动轮播图之后自动轮播失效

加上这句代码,注意swiper是swiper3.x还是swiper4.x
//这是3的写法
 swiperOption: {
        pagination: '.swiper-pagination',
        autoplay: 2000, // 可设置数值来指定播放速度
        autoplayDisableOnInteraction: false,   // 用户操作swiper之后,是否禁止autoplay
        speed: 400,     // 切换图片速度
        loop: true      // 循环播放
      }
//这是4的写法
swiperOption: {
        pagination: '.swiper-pagination',
        autoplay: 2000, // 可设置数值来指定播放速度
        autoplay: {
            disableOnInteraction: false,    // 用户操作swiper之后,是否禁止autoplay
        },
        speed: 400,     // 切换图片速度
        loop: true      // 循环播放
      }

25.vue-cli3.0 buil打包的js文件添加版本号

在vue.config.js中加入下面这段话

const Timestamp = new Date().getTime()
module.exports = {
    configureWebpack: {
        output: {
            //文件名称 版本号 时间戳
            filename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`,
            chunkFilename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`
        }
    }
}

26.assets和static之间的区别

相同点

两个都是存放静态资源文件。项目中所需的资源文件图片,字体图标,样式文件等都可以放在这两个文件下

不同点

1、assets中存放的静态资源文件在项目打包时(npm run build),会将assets中放置的静态资源文件进行打包上传,压缩体积,代码格式化。而压缩后的静态资源文件最终也会放置在static文件中跟着index.html一同上传至服务器

2、static中放置的静态资源文件就不会走打包压缩格式化流程,而是直接进入打包好的目录,直接上传至服务器。因为避免了压缩直接进行上唇,在打包时会提高一定的效率,但是static中的资源由于没有进行压缩等操作,所以文件的体积相对于assets中较大点。在服务器中会占据更大的空间

建议:

将项目中template需要的样式文件、js文件等都可以放置在assets中,走打包这一流程,减少体积。而项目中引入的第三方资源文件如iconfont.css文件等都可以放置在static中,因为这些三方文件已经做过处理,不需要再进行处理,直接上传。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 8,602评论 0 3
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,034评论 1 32
  • Vue 实例 属性和方法 每个 Vue 实例都会代理其 data 对象里所有的属性:var data = { a:...
    云之外阅读 2,122评论 0 6
  • 前端开发面试题 面试题目: 根据你的等级和职位的变化,入门级到专家级,广度和深度都会有所增加。 题目类型: 理论知...
    怡宝丶阅读 2,544评论 0 7
  • 唯闻冷月,惨惨凄凄。 独坐亭间,忆往童归。 十八春秋,技繁叶茂。 不了相思,江水自流。 酌酒自饮,举杯明月。 我心...
    时光的克恒阅读 122评论 0 5