前言

继续总结vue项目实践中的优化和思考

实践问题

批量对象属性赋值

使用场景:主要是针对需要把对象的一些属性批量的赋值到另外一个对象上,然后如果你的属性很多可能要写很多赋值语句。(前提是属性名一般是相同的)

说明:可能有人会问为什么不直接用这个对象,答案也很简单,如果可以直接用,当然直接用是最好的,我自己在写接口param的时候,就会注意这些,需要传参的部分封装到一个特殊的对象里,然后进行data的绑定,这样需要的时候直接用传参对象。但这里讨论的不是这种情况。

  1. //优化前
  2. let data = {}
  3. data.name = this.form.name
  4. data.len = this.form.len
  5. data.amount = this.form.amount
  6. //优化版本一 :利用对象的解构
  7. let {name,len,amount} = this.form
  8. //利用对象解构还可以支持属性名变更的情况
  9. let {name,len:length,amount:money} = this.form
  10. let data = {name,length,money}
  11. //优化版本二 :可以支持批量的导入需要赋值的,对于拷贝对象,用source属性承接,而需要赋值的属性用propArr承接
  12. //在方法中用json的相关方法支持了简单的对象深拷贝
  13. // 批量加载对象属性,支持传入数组[{source:sourceObj,propArr:[]}]
  14. setProps(arr) {
  15. if (arr.length <= 0) return {}
  16. return arr.reduce((acc, item) => {
  17. item.propArr.reduce((acc, prop) => {
  18. if (typeof item.source[prop] === 'object') {
  19. acc[prop] = JSON.parse(JSON.stringify(item.source[prop]))
  20. } else {
  21. acc[prop] = item.source[prop]
  22. }
  23. return acc
  24. }, acc)
  25. return acc
  26. }, {})
  27. }

拓展思考:像这种代码如果你的vue代码里经常写,不妨在你的mixins中混入这个方法,可以为你的页面节省大量的代码空间。

批量变量重置

在我们的代码中经常会遇到把一些变量进行重置,这部分代码重复率很高又没有技术含量,所以我写一个工具方法进行简单的支持,代码优化。

  1. //优化前
  2. this.search = false
  3. this.data = []
  4. this.cur_page = 1
  5. this.pageNo = 1
  6. this.totalCount = 0
  7. this.processType = ''
  8. this.person = ''
  9. this.keyword = ''
  10. this.taskStatus = ''
  11. this.stdate = []
  12. this.processStatus = ''
  13. /**
  14. * @author zhangbing
  15. * @param [] arr 需要重置的数组变量
  16. * @param {*} options 配置对象 对于这里的重置规则如果不符合需求的可以自定义option字典,然后用instanceof 判断类型(todo)
  17. */
  18. resetVars(arr, options) {
  19. if (!arr || arr.length === 0) return
  20. let _options = {
  21. object: {},
  22. string: '',
  23. number: 0,
  24. boolean: true,
  25. null: null,
  26. undefined: undefined
  27. }
  28. _options = options ? Object.assign({}, _options, options) : _options
  29. return arr.map(item => {
  30. if (_options.includes(typeof item)) {
  31. item = _options[typeof item]
  32. } else {
  33. // 不存在重置类型的 重置为字符串
  34. item = ''
  35. }
  36. return item
  37. })
  38. }

拓展思考:像这种代码如果你爹vue代码里经常写,不妨在你的mixins中混入这个方法,可以为你的页面节省大量的代码空间。

骨架屏的相关连接

axios配置的拦截

  • axios模块介绍
    模块的过多介绍这里就不讲了,这里说明的是一个非http 200状态码的错误解析,一般情况下我们会针对response部分做异常解析。
  1. // 配置返回拦截器
  2. _axios.interceptors.response.use(function (response) {
  3. return response
  4. }, function (error) {
  5. if (error.response) {
  6. console.warn(error.response)
  7. return Promise.reject(error.response)
  8. } else {
  9. return Promise.reject(error)
  10. }
  11. })

那么这里就会有一个问题,首先报错中的error是不能直接打印的,如果你写会报错如下:

  1. Request failed with status code 404
  2. at createError (createError.js?8da8:16)
  3. at settle (settle.js?664b:18)
  4. at XMLHttpRequest.handleLoad (xhr.js?ddba:77)

然后针对response存在的情况下,因为这部分的处理是一样的,返回也都在catch里解决的,所以我个人建议直接把错误的提示在这里解决掉,比如通过console.warn的方式或者ui的message.error的方式,这样节省了业务方面的处理错误代码。
但如果你一定希望在接口调用位置处理这部分非http 200的错误,要知道这部分是在catch,error中的,并不是在then中的作用域内。

  1. api.xxx().then(res=> {
  2. //http 200 处理代码
  3. }).catch(error=> {
  4. //非 200处理代码
  5. })

vue元素标签带空格部分使用loader配置去掉

有些时候我们在写模板时不想让元素和元素之间有空格,可能会写成这样:

  1. <ul>
  2. <li>1111</li><li>2222</li><li>333</li>
  3. </ul>

当然还有其他方式,比如设置字体的font-size: 0,然后给需要的内容单独设置字体大小,目的是为了去掉元素间的空格。其实我们完全可以通过配置 vue-loader 实现这一需求。

  1. {
  2. vue: {
  3. preserveWhitespace: false
  4. }
  5. }

它的作用是阻止元素间生成空白内容,在 Vue 模板编译后使用 _v(“ “) 表示。如果项目中模板内容多的话,它们还是会占用一些文件体积的。例如 Element 配置该属性后,未压缩情况下文件体积减少了近 30Kb。

vue-router 路由死循环

下面这个报错是因为路由进入了死循环,需要纠正查看下路由的守卫部分有没有循环,以及设置的拦截、非拦截路径是否正确。

  1. [vue-router] uncaught error during route navigation:
  2. <failed to convert exception to string>

data属性没有设置为函数并返回对象的报错

显性的返回对象就可以了

  1. [Vue warn]: data functions should return an object:

eslint配置自动验证和自动修复

前提:配置了eslint插件并且开启了eslint对文件的格式验证。 默认加了很多eslint规则之后,项目运行就会报错,但实际上肯定是期望软件帮我们自动修正,那么其设置的方法是什么呢?分为两部分,一部分是软件的设置,一部分插件的设置,这里以mac —vscode为例,说明下如何设置自动纠正: 1、window电脑: 文件 > 首选项 > 设置 打开 VSCode 配置文件 2、mac电脑 code>首选项 >设置

  1. "eslint.autoFixOnSave": true,
  2. "eslint.validate": [
  3. "javascript",{
  4. "language": "vue",
  5. "autoFix": true
  6. },"html",
  7. "vue"
  8. ],

备注:如果你不想在项目中使用eslint,其在config/index.js,dev配置中,useEslint: true ,设置为false即可。

vue路由拦截实现保存用户信息

场景:为了防止用户突然离开,没有保存已输入的信息。

  1. //在路由组件中:mounted(){},
  2. beforeRouteLeave (to, from, next) {
  3. if(用户已经输入信息){
  4. //出现弹窗提醒保存草稿,或者自动后台为其保存
  5. }else{
  6. next(true);//用户离开
  7. }
  8. }

监听封装多条件对象

场景:一般这种情况是多个条件都会导致执行同一个方法,比如我们经常写的搜索,每个搜索条件变化都会引起重新执行搜索列表,那么每个条件变化监听后都去执行,有些繁琐。因此,我们进行一步优化。

将所有的条件封装到同一个对象内,然后监听这个对象,当这个对象深度监听时发生任何变化都执行搜索方法。

那么引发的第二个问题是:如果是多个条件之间有差异怎么办?比如某些条件变化会引起另外一些条件的重置,或者处于其他目的,我们需要细致区分到底是哪个属性发生了变化。针对这两个问题建议如下:

1 搜索方法的执行只关注能引起搜索的直接参数,其他的不去关心
2 写一个检索判断出属性变化的工具方法,可以检测出两个对象是具体哪个属性有差异,具体差异属性的计数,返回对比结果。