1.vue2和vue3区别
1.双向数据绑定
vue2是通过ES5的Object.definedProperty()对数据进行劫持结合发布-订阅模式来实现双向数据绑定;
vue3是通过ES6的Proxy API对数据代理来监听属性的变化,从而实现对数据的监控。
Proxy优势如下:
- Object.definedProperty()只能遍历对象属性进行劫持;Proxy可以劫持整个对象,并返回一个新的对象;
- Object.definedProperty()无法监听数组,vue2需要重写数组方法,额外增加set、delete方法;Proxy可以监听数组,不用单独对数组进行特异性操作;
- Proxy有多种拦截方法,如deleteProperty、ownKeys等等。
2.生命周期
| vue2 | vue3(setup) | 描述 |
|---|---|---|
| beforeCreate | setup() | 创建实例前 |
| created | setup() | 创建实例后 |
| beforeMount | onBeforeMount | DOM挂载前调用 |
| mounted | onMounted | DOM挂载后调用 |
| beforeUpdate | onBeforeUpdate | 数据更新之前调用 |
| updated | onUpdated | 数据更新之后调用 |
| beforeDestroy | onBeforeUnmount | 组件销毁前调用 |
| destroyed | onUnmounted | 组件销毁后调用 |
3.新增了Composition API
vue2使用Options API,通过定义data,methods,computed,watch等属性与方法,共同处理页面逻辑,当组件变得复杂,导致页面对应属性的列表也会增长,导致组件难以阅读和理解;
vue3推出了Composition API,组件根据逻辑功能来组织,一个功能所定义的所有API放在一起(高内聚,低耦合)
2.nextTick API的作用
Vue在更新DOM时是异步执行的,当数据发生变化,Vue将开启一个异步更新队列,视图需要等待队伍中所有数据变化完成后,再进行统一更新。
1.使用场景
希望在修改数据后立刻更新DOM结构,可使用nextTick
2.实现原理
- 把回调函数放入callbacks等待执行
- 将执行函数放到微任务或者宏任务中
- 事件循环到了微任务或者宏任务,执行函数依次执行callbacks中的回调
宏任务包括:setTimeout setInterval Ajax DOM事件
微任务:Promise async/await
微任务比宏任务执行时间早
3.ref和reactive区别
- ref通过Object.defineProterty()的get和set来实现响应式;reactive通过Proxy来实现响应式,并通过Reflect操作源对象内部的数据
- ref多用来定义基本数据类型(也可定义对象,内部会自动通过reactive转为代理对象),而reactive只能用来定义对象数组类型
- ref操作需要.value(在模板template中使用时不需要.value,会自动解包),reactive操作数据不需要.value
4.keep-alive作用及参数
keep-alive是Vue内置的组件,可以使被包含的组件保留状态,或避免重新渲染。
被包含在keep-alive中创建的组件,会多出两个生命周期的钩子:activated和deactivated:
- activated当keep-alive包含的组件再次渲染的时候触发
- deactivated当keep-alive包含的组件销毁的时候触发
参数情况
keep-alive可以接收3个属性作为参数进行匹配对应的组件进行缓存
- include:包含的组件,可以为字符串,数组以及正则表达式,只有匹配的组件会被缓存
- exclude:排除的组件,可以为字符串,数组以及正则表达式,匹配的组件不会被缓存
- max:缓存组件的最大值,可以为字符或者数字,控制缓存组件的个数
5.watch和watchEffect区别
watch:既要指明监听的属性,也要指明监听的回调。默认是惰性执行(设置immediate:true时为非惰性,页面首次加载时就会执行),监听源可以是具有返回值属性的getter函数,也可以直接是一个ref
watchEffect:不用指明监听哪个属性,监听回调中用到哪个属性就监听哪个属性,会根据其中的属性,自动监听其变化
6.聊一聊虚拟DOM
真实的DOM节点,哪怕一个最简单的div也包含这很多属性,操作DOM的代价是昂贵的,频繁操作还会出现页面卡顿,影响用户体验。
虚拟DMO的本质是用树形结构的js对象来描述真实的DOM结构的信息,这个树结构的js对象包含了整个DOM结构的信息。
1.虚拟DOM的优缺点
优点:
- 降低浏览器性能消耗,因为js对象的运算速度远大于DOM操作的执行速度
- diff算法,减少回流和重绘(触发回流一定会触发重绘)
- 跨平台,虚拟DOM本质是js对象,而DOM与平台强相关,相比之下虚拟DOM可以进行更方便地跨平台操作,例如:服务器渲染、weex开发等等
缺点:
- 首次显示较慢,首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢
- 无法进行极致优化
2.虚拟DOM实现原理
- 用js对象结构表示DOM树的结构
- 当数据状态变更的时候,重新构造一棵新的对象树,通过diff算法,比较新旧虚拟DOM树的差异
- 根据差异,对真正的DOM树进行增删改
7.渲染函数 & JSX
1.渲染函数介绍
在绝大多数情况下,Vue推荐使用模板语法来创建应用,然而某些场景下,我们真的需要用到js完全的编程能力,即使用渲染函数用js构建DOM。
2.渲染函数的基本用法
1.创建Vnodes(虚拟节点)
Vue提供了一个h()函数用于创建vnodes(类型必填,其它参数可选)
import { h } from 'vue'
const vnode = h( 'div', // type
{ id: 'foo', class: 'bar' }, // props
[
/* children */
] )
2.声明渲染函数
使用render选项来声明渲染函数:
import { h } from 'vue'
export default {
data() {
return {
msg: 'hello'
}
},
render() {
return h('div', this.msg)
}
}
render()函数可以访问同一个this示例,除了返回一个单独的vnode之外,还可以返回字符串或是数组。
3.Vnodes必须唯一
组件树中的vnodes必须是唯一的。
3.JSX/TSX
JSX是js的一个类似XML的扩展,在jsx文件中,有如下写法(使用大括号来嵌入动态值)
const vnode = <div>hello</div>
const vnode = <div id={dynamicId}>hello, {name}</div>
8.vue3如何设计公共方法
- main.js文件中:app.config.globalProperties添加
- main.js文件中:app.mixin添加
9.vuex如何设计
1.基本定义
Vuex是专为Vue.js应用程序开发的状态管理模式+库,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
使用场景:在中大型单页面应用中,需要考虑组件外部管理状态
2.五个核心概念
- state:vuex的基本数据,用来存储变量,定义我们所需要管理的数组、对象、字符串等
- getters:从基本数据(state)派生的数据,相当于state的计算属性,getter会接收state作为第一个参数,而且getter的返回值会根据它的依赖被缓存起来,只有getter中的依赖值(state中的某个需要派生状态的值)发生改变的时候才会被重新计算
- mutations:提交更新数据的方法,必须是同步的,每个Mutation都有一个字符串的事件类型(type)和一个回调函数(handler),state作为第一个参数,提交载荷作为第二个参数,执行回调函数方法:store.commit
- actions:action类似于mutation,不同在于:action提交的是mutation,而不是直接变更状态;action可以包含任意异步操作。action通过store.dispatch方法触发
- modules:模块化vuex,每一个模块拥有自己的state、mutation、action、getter,使得结构清晰,便于管理
3.store目录结构
|--modules
|--user.js
|--getters.js
|--index.js
index.js文件如下:
import { createStore } from 'vuex'
import user from './modules/user'
import getters from './getters'
const store = createStore({
modules: {
user
},
getters
})
export default store
modules/user.js文件如下:
const user = {
state: {
userInfo: getStore({
name: 'userInfo'
}) || {}
},
actions: {},
mutations: {}
}
export default user
getters.js文件如下:
const getters = {
userInfo: state => state.user.userInfo
}
export default getters
4.pinia和vuex区别
- pinia是轻量级的,体积小,适用于中小型应用;vuex是重量级的,适用于大规模、复杂的项目
- pinia没有mutations,只有state, getters, actions(同步、异步)
- pinia没有modules配置,每一个独立的仓库都是defineStore生成的
10.vue中的mixin混入
mixin(混入),来分发vue组件中的可复用功能,其本质是一个js对象,可以包含我们组件中任意功能选项,如data、components、methods、created、computed等等
var myMixin = {
created: function() {
this.hello();
},
methods: {
hello: function() {
console.log('hello world');
}
}
}
组件通过mixins属性调用mixin对象
Vue.component('componentA', {
mixins: [myMixin]
})
当组件存在与mixin对象相同的选项的时候,进行递归合并的时候组件的选项会覆盖mixin的选项;当相同选项为生命周期钩子的时候,会合并成一个数组,先执行mixin钩子,再执行组件的钩子