vite
前端构建工具,最初是为了vue3.0项目一起使用,现在可以构建vue,react,preact框架
特点
快速冷启动
即时的模块热更新
真正的按需编译
vite和vue-cli的区别
vue-cli在开发模式下必须对整个项目进行打包才能运行,vite在开发模式下则不需要打包,使用es6模块化加载规则,实现了真正的按需编译
vue-cli是基于webpack的热更新,而vite则是基于缓存的热更新
执行脚本
- 安装
npm i -g create-vite-app
- 创建项目
create-vite-app myproject
vue3.0
vue3.0亮点
1、 peformance: 性能更快,比vue2.0块1.2~2.0倍
2. Tree shaking support:按需编译,体积更小
3. Composition API: 组合式API
4. Better Ttypescript Support:更好的TS支持
5. Custom Render API:暴露了自定义渲染API
6. Fragment Teleport(Portal) Suppose: 更先进的组件
diff算法的优化
- vue2.0中虚拟dom进行全量对比
- vue3.0中新增了静态标记(PatchFlag)
- 在与上次的节点对比时候,只针对带有Patch flag的节点进行对比
- 可以通过flag的信息获取要对比节点的具体内容
- 静态标记的添加:创建虚拟DOM的时候,会根据节点中的内容是否会变化,添加静态标记
静态提升
- 默认情况下无论元素是否参与更新,每次都会重新创建一次,然后再重新渲染
- vue3.0中针对不参与更新的元素会做静态提升,只创建一次,渲染时直接复用
事件侦听缓存
- 默认情况下中onClick因为是动态绑定事件,所以会追踪变化
- vue3.0中因为事件绑定的是同一个函数,所以不再去追踪变化,直接缓存起来复用
SSR渲染
。。。。
组合式API
steup
- steup是组合式api的入口
- steup发生在组件创建执行之前,所以在steup中要避免使用this,这里获取不到data,method中的数据
- steup选项是一个接收context,prop的函数,steup中返回的内容将暴漏给组件的其余选项(data,computed等)以及组件模板
- prop参数
- context参数
- ref函数只能监听简单类型的变化
- reactive函数可以监听负责数据类型的变化
// ref函数只能监听简单数据类型
import { ref } from ‘vue’
// 组合式api中可以定义变量和 方法
setup(prop, context){
// 定义一个count变量,初始值为0,变量发生变化后视图可以自动更新,ref 使得视图自动更新
let count = ref(0)
// 只有在此处返回的内容才可以用于组件其余部分,例如视图
return {
count,
}
}
// reactive函数可以监听复杂数据类型
import {reactive} from 'vue'
setup(){
let state = reactive({
arr: [1,2,3]
})
return {
state
}
}
生命周期执行顺序
1、setup
2. beforeCreate
3. created
4. beforeMount
5. mounted
6. beforeUpdate
7. updated
8. beforeDestory
9. destoryed
reactive
reactive介绍–数据响应式
- 在vue2.0中通过defineproperty实现数据的响应式处理
- 在vue3.0中通过ES6的Proxy实现数据的响应式
reactive注意点
- reactive的参数必须是对象(JSON/arr),否则将不会包装成Proxy对象,不会实现响应式
- 如果给reactive传递了其他对象,默认情况下修改对象界面不会更新,如果想更新可以通过重新赋值的方式
<div>{{state.time}}</div>
<button @click="myFn">btn</button>
import {reactive} form 'vue'
export default {
name: 'App',
setup(){
let state = reactive({
time:new Date(),
arr:[1,2]
})
let myFn = ()=>{
// 没有重新赋值,不会响应式修改到页面
state.time.setDate(new Date(state.time.getDate + 1))
// 重新赋值后,可以响应式到页面
state.time = state.time.setDate(new Date(state.time.getDate + 1))
}
return { myFn, state } }}
ref
理解
- ref和reactive一样,都是为了实现数据的响应式处理
- reactive多是为了处理复杂数据的响应式,所以vue3.0提供了ref,用于处理简单数据类型的响应式
本质
ref本质也可以理解为是reactive,ref底层根据我们传递给ref的数据进行转换
ref(123)----> reactive({value:123})
怎么判断是否为ref类型数据
根据数据的__V_ref的属性值是否为true,如果属性值为true,则是ref类型,自动进行转换。
注意点
- 在html中使用ref的值不需要通过value获取,vue会自动添加.value
- 在js中使用ref的值,必须通过.value获取
<!-- html中ref的值不需要通过value获取-->
<div>{{age}}</div>
<button @click="myFn">btn</button>
import {ref} from 'vue'
export default {
setup(){
let age = ref(12)
let myFn = ()=>{
// js中必须通过.value 设置
age.value = 999
}
return { age, myFn}
}
}
// 判断ref,reactive数据类型
import {isRef, isReactive} from 'vue'
import {ref,reactive} from 'vue';
export default {
setup(){
let age = ref(12)
let state = reactive({name:'www'})
let myFn = ()=>{
// js中必须通过.value 设置
age.value = 999
let a = isRef(age) // 返回true or false
let b = isReactive(state) //返回true or false
}
return { age, myFn}
}
}
递归监听 and 非递归监听
递归监听
vue3.0中通过递归监听,来监听ref和reactive中的数据,通过递归监听,将每一层的数据包装成了一个Proxy对象,但是递归监听会大大降低数据的性能
非递归监听
vue3.0中通过shallowRef和shallowReactive实现非递归监听。
shallowReactive仅会监听第一层的数据 ,将第一层的数据包装成Proxy对象,如果第一层数据不发生变化的情况下,视图将不会同步更新被修改的数据。
shallowRef仅会监听.value的变化,只有.value发生变化时,视图才会更新。如果仅需要更新某一层的数据,则可以调用trrigerRef重新进行对ref赋值
import { shallowRef, trigerRef} from 'vue'
export default {
setup(){
let a = shallowRef({
b: 1,
c: {
d: 2
}
})
a.d = 3
trigerRef(a)
return {a}
}
}
toRaw
因为ref/reactive的修改会实时更新UI视图,如果存在一些不需要实时更新视图的数据的时候,则会导致性能降低。
toRaw方法则可以解决此类问题,通过toRaw方法拿到ref/reactive中的原始数据,进行修改,且不会更新视图
import { reactive,toRaw} from 'vue'
export default {
setup(){
let obj = {a:1,b:2}
let state = reactive(obj)
let obj2 = toRaw(state)
obj === obj2 // true,通过toRaw拿到obj的原始数据
return {obj}
}
}
markRaw
markRaw的数据不会被追踪 ,ui视图不会被更新
toRef
toRef,更新响应式数据,且会修改原始数据,但是不会导致UI视图更新
ref和toRef的区别:
ref:复制,修改数据不会影响原始数据,属于深拷贝,修改响应式数据会更新视图层
toRef:引用,修改会影响原始数据,属于浅拷贝,修改响应式数据,不会更新视图层
import { toRef, toRefs} from 'vue'
export default {
setup(){
let obj = {a:1,b:2}
let a = toRef(obj,'a') // toRef只能修改对象中的某一个属性
let state = toRefs(obj) // toRefs可以修改对象中的所有属性
a.value = 3 // 数据修改,但是视图不更新
state.a.value = 4
return {obj}
}
}
customRef
返回一个ref对象,可以显示的控制依赖追踪和触发响应,自定义ref
setup只能是一个同步函数,不能是异步函数,所以不可以使用async,await
customRef可以用来获取异步的数据
import {customRef} from 'vue'
// 自定义ref
function async myRef(value){
let res
// 发送网络请求,获取异步数据
const data = fetch(value)
res = data
trigger()
return customRef((track, trigger)=>{
return {
get(){
track() // 追踪变化
return res
},
set(newvalue){
res = newvalue
trigger() // 数据变化,触发视图更新
}
}
})
}
export default {
setup(){
// 使用自定义的ref
let age = myRef(123)
age.value = 345
return age
}
}
readonly家族
readonly创建只读数据,递归只读
shallowReadonly:创建只读数据,非递归只读
isReadonly:返回布尔值
vue3响应式数据原理
vue3是通过proxy实现数据的响应式
let obj = {a:1,b:2}
let state = new Proxy(obj,{
get(obj,key){
return obj[key]
},
set(obj,key,value){
obj[key] = value
return true
}
})