关于iview中Slider组件@on-input和@on-change事件重复触发引发的渲染性能问题
<template>
<div style="width:200px">
<Slider show-input inputSize="small" v-model="value" @on-input="input" @on-change="change"></Slider>
<button @click="add">点击</button>
</div>
</template>
<script>
export default {
data(){
return{value:0}
},
methods:{
add(){
this.value++;this.render()
},
input(value){
console.log('input',value);
this.render()
},
change(value){
console.log('change',value)
this.render()
},
render(){
console.time('dom');
for(let i=0;i<1e4;i++)
document.title=i;
console.timeEnd('dom')
}
}
}
</script>
以上是一段测试代码
页面如下:

实际开发过程中使用到这个iview组件库中的Slider滑块组件,并且同时会存在3个地方修改value值
1.滑块滑动会触发事件render
2.输入框输入也会触发render
3.点击按钮也会触发render
4.render是一个比较耗时的操作时此时就是会比较影响性能
5.此时给Slider添加事件 @on-input="input" @on-change="change" ,滑块滑动时input事件和change事件都会触发,打印多次

6.如果点击按钮时滑块滑动时input事件和change事件都会触发,此时会打印多次

7.所以针对5.6中的多次触发事件导致重复渲染,如果你此时代码中有比较耗性能的操作就会有影响
8.后来发现只要在@on-input上加上.native修饰符就ok了,事件触发都是独立的,不会重复
回头去看一下官网的Slider组件是这么说的

on-input事件时滑动条的数据发生变化就会触发
Vue 中 .native 修饰符的作用是:在一个组件的根元素上直接监听一个原生事件。
我理解的主要的原理应该是事件捕获,加上了.native就不让事件向下传递了,不会导致原生input的input方法也触发了,而是只要操作之后才监听到事件
虽然只是一个小小的改动,但是再实际开发过程中,经常会遇到一些性能问题,排查很久之后才发现就是小小的地方导致的,确实是很坑。

浙公网安备 33010602011771号