1、nextTick知道吗、实现的原理是什么?是宏任务还是微任务?
微任务
原理:nextTick方法主要是使用了宏任务和微任务,定义了一个异步方法,多次调用nextTick会将方法存入队列中,通过这个异步方法清空队列。
作用: nextTick用于下次Dom更新循环结束之后执行延迟回调,在修改数据之后使用nextTick用于下次Dom更新 循环结束之后执行延迟回调,在修改数据之后使用nextTick用于下次Dom更新循环结束之后执行延迟回调,在修改 数据之后使用nextTick,则可以在回调中获取更新后的DOM。
2、虚拟 dom 为什么会提高性能?
虚拟DOM其实就是一个JavaScript对象。通过这个JavaScript对象来描述真实DOM,真实DOM的操作,一般都会 对某块元素的整体重新渲染,采用虚拟DOM的话,当数据变化的时候,只需要局部刷新变化的位置就好了,虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。
具体实现步骤如下:
- 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中;
- 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异;
- 把2所记录的差异应用到步骤1所构建的真正的 DOM 树上,视图就更新。
3、你做过哪些Vue的性能优化?
- 首屏加载优化
- 路由懒加载
{
path: '/',
name: 'home',
component: () => import('./views/home/index.vue'),
meta: { isShowHead: true }
}
- 开启服务器 Gzip 开启 Gzip 就是一种压缩技术,需要前端提供压缩包,然后在服务器开启压缩,文件在服务器压缩后传给浏览器, 浏览器解压后进行再进行解析。首先安装 webpack 提供的 compression-webpack-plugin 进行压缩,然后在 vue.config.js:
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const productionGzipExtensions = ['js', 'css']......plugins: [
new CompressionWebpackPlugin({
algorithm: 'gzip',
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
threshold: 10240,
minRatio: 0.8
}
)]
- 启动 CDN 加速
我们继续采用 cdn 的方式来引入一些第三方资源,就可以缓解我们服务器的压力,原理是将我们的压力分给其他服务器点。
- 代码层面优化
- computed 和 watch 区分使用场景
computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取computed 的值时才会重新计算 computed 的值。当我们需要进行数值计算,并且依赖于其它数据时,应该使用computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算。
watch:类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;当我们需要在数据变化时 执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
- v-if 和 v-show 区分使用场景 v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。这里要说的优化点在于减少页面中 dom 总数,我比较倾向于使用 v-if,因为减少了 dom 数量。
- v-for 遍历必须为 item 添加 key,且避免同时使用 v-if v-for 遍历必须为 item 添加 key,循环调用子组件时添加 key,key 可以唯一标识一个循环个体,可以使用例如 item.id 作为 key 避免同时使用 v-if,v-for 比 v-if 优先级高,如果每一次都需要遍历整个数组,将会影响速度。
- Webpack 对图片进行压缩
- 避免内存泄漏
- 减少 ES6 转为 ES5 的冗余代码
4、Vue的常用修饰符
一、v-model修饰符
1、.lazy:
输入框改变,这个数据就会改变,lazy这个修饰符会在光标离开input框才会更新数据:
<input type="text" v-model.lazy="value">
2、.trim:
输入框过滤首尾的空格:
<input type="text" v-model.trim="value">
3、.number:
先输入数字就会限制输入只能是数字,先字符串就相当于没有加number,注意,不是输入框不能输入字符串,是这个数据是数字:
<input type="text" v-model.number="value">
二、事件修饰符
4、.stop:
阻止事件冒泡,相当于调用了event.stopPropagation()方法:
<button @click.stop="test">test</button>
5、.prevent:
阻止默认行为,相当于调用了event.preventDefault()方法,比如表单的提交、a标签的跳转就是默认事件:
<a @click.prevent="test">test</a>
6、.self:
只有元素本身触发时才触发方法,就是只有点击元素本身才会触发。比如一个div里面有个按钮,div和按钮都有事件,我们点击按钮,div绑定的方法也会触发,如果div的click加上self,只有点击到div的时候才会触发,变相的算是阻止冒泡:
<div @click.self="test"></div>
7、.once:
事件只能用一次,无论点击几次,执行一次之后都不会再执行。
<div @click.once="test"></div>
8、.capture:
事件的完整机制是捕获-目标-冒泡,事件触发是目标往外冒泡。
9、.sync
对prop进行双向绑定
10、.keyCode:
监听按键的指令,具体可以查看vue的键码对应表
5、谈谈你对Vue3.0有什么了解?
一、六大亮点
- 性能比vue2.x 快1.2~2倍
- 支持tree-shaking,按需编译,体积比vue2.x 更小
- 支持组合API
- 更好的支持TS
- 更先进的组件
二、性能比vue2.x 快1.2~2倍如何实现的呢
- diff算法更快
vue2.0是需要全局去比较每个节点的,若发现有节点发生变化后,就去更新该节点vue3.0是在创建虚拟dom中,会根据DOM的的内容会不会发生内容变化,添加静态标记,谁有 flag! 比较谁。
- 静态提升
vue2中无论元素是否参与更新,每次都会重新创建,然后再染 vue3中对于不参与更新的元素,会做静态提升只被创建一次,在渲染时直接复用即可。
- 事件侦听缓存
默认情况下,onclick为动态绑定,所以每次都会追踪它的变化,但是因为是同一函数,没有必要追踪变化,直接缓存复用即可。
在之前会添加静态标记8 会把点击事件当做动态属性会进行diff算法比较,但是在事件监听缓存之后就没有静态标记了,就会进行缓存复用。
为什么vue3.0体积比vue2.x小
在vue3.0中创建vue项目 除了vue-cli,webpack外还有一种创建方法是Vite Vite是作者开发的一款有意取代webpack的工具,其实现原理是利用ES6的import会发送请求去加载文件的特性,拦截这些请求,做一些预编译省去webpack元长的打包时间。
6、vue3.0组合API
说一说vue3.0的组合API跟之前vue2.0在完成业务逻辑上的区别:
在vue2.0中: 主要是往data 和method里面添加内容,一个业务逻辑需要什么data和method就往里面添加,而组合API就是有一个自己的方法,里面有自己专注的data 和method。
再说一下组合APl的本质是什么: 首先composition API(组合API) 和 Option API (vue2.0中的data和method)可以共用composition API (组合API)本质就是把内容添加到Option API中进行使用。
7、ref和reactive的简单理解
-
re和reactive都是vue3的监听数据的方法,本质是proxy
-
ref 基本类型复杂类型都可以监听(我们一般用ref监听基本类型),reactive只能监听对象 (arr, json)
-
ref底层还是reactive,ref是对reactive的二次包装,ref定义的数据访问的时候要多一个.value
8、Vuex和redux有什么区别?他们的共同思想。
Redux和Vuex区别
-
Vuex改进了Redux中的Action和Reducer函数,以mutations变化函数取代Reducer,无需switch,只需在对应的mutation函数里改变state值就可以
-
Vuex由于Vue自动重新渲染的特性,无需订阅重新渲染函数,只要生成新的state就可以
-
Vuex数据流的顺序是:View调用store.commit提交对应的请求到Store中对应的mutation函数 -- store改变(vue检测到数据变化自动渲染)
共同思想
- 单一的数据源
- 变化可以预测
- 本质上:Redux和Vuex都是对MVVM思想的服务,将数据从视图中抽离的一种方案
- 形式上:Vuex借鉴了Redux,将store作为全局的数据中心,进行数据管理
9、简单说一下微信小程序与Vue 的区别
1、生命周期:
小程序的钩子函数要简单得多。 vue 的钩子函数在跳转新页面时,钩子函数都会触发,但是小程序的钩子函数页面不同的跳转方式,触发的钩子并不一样。
在页面加载请求数据时,两者钩子的使用有些类似,vue 一般会在created或者 mounted中请求数据,而在小程序,会在onLoad或者onshow中请求数据。
2、数据绑定:
vue动态绑定一个变量的值为元素的某个属性的时候,会在变量前面加上冒号:
<img :src="imgSrc" />
小程序 绑定某个变量的值为元素属性时,会用两个大括号括起来,如果不加括号,为被认为是字符串
<image src="{{imgsrc}}"></image>
3、列表循环
4、显示与隐藏元素
vue中,使用v-if和v-show控制元素的显示和隐藏
小程序中,使用wx-if和hidden控制元素的显示和隐藏
5、事件处理
vue:使用v-on:event绑定事件,或者使用@event绑定事件
小程序中,全用bindtap(bind+event),或者catchtap(catch+event)绑定事件
6、数据的双向绑定
在vue中,只需要再表单元套上加上v-mode1,然后再绑定data中对应的一个值,当表单元素内容发生变化时data中对应的值也会相应改变。
当表单内容发生变化时,会触发表单元素上绑定的方法,然后在该方法中,通过 this.setData({key:value》)来将表单上的值赋值给data中的对应值。
7、绑定事件传参
在vue 中,绑定事件传参挺简单,只需要在触发事件的方法中,把需要传递的数据作为形参传入就可以了。
在小程序中,不能直接在绑定事件的方法中传入参数,需要将参数作为属性值,绑定到元素上的 data-属性上然后在方法中,通过e.currentTarget.dataset.*的方式获取。
8、父子组件通信
父组件向子组件传递数据,只需要在子组件通过v-bind传入一个值,在子组件中,通过 props 接收,即可完成数 据的传递
父组件向子组件通信和 vue 类似,但是小程序没有通过v-bind,而是直接将值赋值给一个变量 在子组件properties中,接收传递的值
写在最后
码字不易,谢谢关注、点赞和转发。
越笨拙,越努力; 越努力,越幸运; 大家加油!