Vue使用中遇到问题汇总(三)

1、后台session过期前端跳转到登录页面

  axios 拦截器 可以拦截请求和返回,对于失效的情况后端可以返回一个状态码,如401, 使用axios拦截时判断是401,则跳转到指定页面,如login。本人项目中开发还没定接口规范,后端返回的就是success:true/false

axios.interceptors.response.use((response) => {
    if (response.data.success === false) {
          router.push('/login')
          message({
            message:'会话失效,请重新登陆',
            type:'error'
        })
          return response
    } else {
          return response
    }
}, (error) => {
    return Promise.reject(error)
})

2、定义全局函数或变量

  许多时候我们需要定义一些全局函数或变量,来处理一些频繁的操作(这里拿 AJAX 的异常处理举例说明)。但是在 Vue 中,每一个单文件组件都有一个独立的上下文(this)。通常在异常处理中,需要在视图上有所体现,这个时候我们就需要访问 this 对象,但是全局函数的上下文通常是 window,这时候就需要一些特殊处理了。

  简单粗暴型:

  最简单的方法就是直接在 window 对象上定义一个全局方法,在组件内使用的时候用 bindcallapply 来改变上下文。

  定义一个全局异常处理方法:

// errHandler.js
window.errHandler = function () { // 不能使用箭头函数
  if (err.code && err.code !== 200) {
    this.$store.commit('err', true)
  } else {
    // ...
  }
}

//在入口文件中导入:
// src/main.js
import 'errHandler.js'

//在组件中使用:
// xxx.vue
export default {
  created () {
    this.errHandler = window.errHandler.bind(this)//绑定this
  },
  method: {
    getXXX () {
      this.$http.get('xxx/xx').then(({ body: result }) => {
        if (result.code === 200) {
          // ...
        } else {
          this.errHandler(result)
        }
      }).catch(this.errHandler)
    }
  }
}

  优雅安全型做法:

  在大型多人协作的项目中,污染 window 对象还是不太妥当的。特别是一些比较有个人特色的全局方法(可能在你写的组件中几乎处处用到,但是对于其他人来说可能并不需要)。这时候推荐写一个模块,更优雅安全,也比较自然,唯一不足之处就是每个需要使用该函数或方法的组件都需要进行导入。比如我经常把一些公共的方法写在utils里面,如果哪个组件需要就直接导入方法使用即可,推荐这种方式,前面介绍只是一个思路引子而已。

3、setInterval路由跳转继续运行并没有及时进行销毁

  比如一些弹幕,走马灯文字,这类需要定时调用的,路由跳转之后,因为组件已经销毁了,但是setInterval还没有销毁,还在继续后台调用,控制台会不断报错,如果运算量大的话,无法及时清除,会导致严重的页面卡顿。

  解决方案:在组件生命周期beforeDestroy停止setInterval

beforeDestory() {
    clearInterval(this.timer);
    MessageBox.close()                
}

4、图片验证码,视频等资源,浏览器自动解析

<el-dialog class="dialogStyle" center top="0" custom-class="vertical-horizontal" title="查看录像" :visible.sync="videoShow" width="70%">
    <video controls>
        <source :src="videoApi" type="video/mp4">
    </video>
</el-dialog>

//查看录像
viewVideo(row){
    this.videoShow = true
    this.videoApi = "/api/up/playVideo?video_path=" + row.video_path
    //videoApi 直接给接口,及传参即可    
}

5、ES6 import 引用问题

  在 ES6 中,模块系统的导入与导出采用的是引用导出与导入(非简单数据类型),也就是说,如果在一个模块中定义了一个对象并导出,在其他模块中导入使用时,导入的其实是一个变量引用(指针),如果修改了对象中的属性,会影响到其他模块的使用。

  通常情况下,系统体量不大时,我们可以使用 JSON.parse(JSON.stringify(str)) 简单粗暴地来生成一个全新的深度拷贝的 数据对象。不过当组件较多、数据对象复用程度较高时,很明显会产生性能问题,这时我们可以考虑使用 Immutable.js

  鉴于这个原因,进行复杂数据类型的导出时,需要注意多个组件导入同一个数据对象时修改数据后可能产生的问题。

  此外,模块定义变量或函数时即便使用 let 而不是 const,在导入使用时都会变成只读,不能重新赋值,效果等同于用 const 声明。

6、图片上传与预览

  问题描述: 有时候可能会有这样的需求,需要通过<input type="file">标签上传一个头像,然后在特定的位置预览头像。

  解决方法: 预览 (1)添加一个<img :src="image">标签,图片路径绑定实例数据 (2)给<input type="file">添加一个事件@change="onFileChange",(3)onFileChange方法如下:

onFileChange: function(){
    if (typeof FileReader == 'undefined') {
        console.log('failed');
        return false;
    }
    var file = document.getElementById('file').files[0];
    var reader = new FileReader();
    reader.readAsDataURL(file);
    var vm = this;
    reader.onload = function(e) {
        vm.image = e.target.result;
    }
}

7、vue 滚动行为用法,进入路由需要滚动到浏览器底部、头部等等

  使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。 注意:这个功能只在

const router = new  VueRouter({
  mode: 'history',
  scrollBehavior (to, from, savedPosition) {
    if (savedPosition) { //如果savedPosition存在,滚动条会自动跳到记录的值的地方
      return savedPosition
    } else{
      return { x: 0, y: 0}//savedPosition也是一个记录x轴和y轴位置的对象
    }
  },
  routes: [...]
})

8、实现vue路由拦截浏览器的需求,进行一系列操作,如草稿保存等等

  为了防止用户失误点错关闭按钮等等,导致没有保存已输入的信息(关键信息)。

  解决方法:在beforeRouteLeave钩子中执行相应操作

beforeRouteLeave (to, from, next) {  
  if(用户已经输入信息){
        //出现弹窗提醒保存草稿,或者自动后台为其保存
  }else{
      next(true);//用户离开
  }
}

9、v-once 只渲染元素和组件一次,优化更新渲染性能

  v-once 这个指令相信大家用的很少,不过个人感觉还是挺实用的!

  只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

10、关于在vue中如何操作DOM元素。

  我们都知道vue框架中我们一般操作的都是数据,那么假如我们要操作dom元素使用什么方法呢?下面就来介绍一下!

  假如有以下元素,我们要获取这个h2元素的文本,需要给此元素添加ref属性,并赋予名字。

<h2 ref='foo'>我是ref的值</h2>

  接下来就可以使用这个方法获取到它的文本(注意是this.$refs不是this.$ref):

console.log(this.$refs.foo.innerHTML)
//如何改变h2中的文本呢?
this.$refs.foo.innerHTML='我是新值'

  这样就可以和以前一样,轻松的操作dom元素了,但是vue还是以操作数据为核心,所以建议尽量少的使用以上方法。

11、element的tooltip修改默认样式问题

  通过使用tooltip的popper-class属性设置自定义class,但是发现在本组件给class设置样式会无效,最后发现tooltip生成的元素是在最外层,所以只能把class设置的样式移到App.vue,样式生效了

.el-tooltip__popper.is-light.tooltipStyle{
  border 1px solid #eee
  width 80px
  word-break break-all
}

 

原文地址:https://www.cnblogs.com/goloving/p/9122710.html