学习vue3
程序员文章站
2022-05-17 20:31:48
...
一、了解vue3
vee3是如何变快的?
diff算法优化
vue2中的虚拟dom是进行全量的对比
vue3新增了静态标记(PatchFlag)
hoistStatic静态提升
vue2中无论元素是否参与更新,每次都会重新创建,然后再渲染
vue3中对于不参与更新的元素,会做静态提升,只会被创建一次,再渲染时直接复用即可
cacheHandlers 事件侦听器缓存
默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化,
但是因为是同一个函数,所以没有追踪变化,直接缓存起来复用即可
ssr 渲染
什么是vite?
vite是vue作者开发的一款意图取代webpack的工具
实现原理是利用ES6的import会发送请求去加载文件的特性,
拦截这些请求,做一些预编译,省去webpack冗长的打包时间
安装vite
npm install -g create-vite-app
利用vite创建vue3项目
create-vite-app projectName
安装依赖运行项目
cd projectName
npm install
npm run dev
二、vue3中的一些API
- reactive本质:就是将传入的数据包装成一个Proxy对象
- ref本质:包装成一个带value的属性传入reactive ref(666) -> reactive({value:666})
注意:ref和reactive都是递归监听(如果数据量比较大,非常消耗性能) - shallowReactive只监听第一层的变化
- shallowRef监听的是.value的变化,并不是第一层的变化 (因为底层本质上value才是第一层)
- triggerRef触发界面更新 (ref数据类型)
注意:vue3没有提供triggerReactive方法,所以reactive类型的数据无法主动触发界面更新 - toRaw返回reactive或readonly代理的原始对象
- markRaw标记一个对象,使其永远不会转换为proxy。返回对象本身
- toRef
toRef->引用 修改响应式数据会影响到以前的数据,且数据发生改变,界面不会自动更新
ref->复制 修改数据不会影响到以前的数据且界面会自动更新 - customRef 自定义一个ref
function myRef(value){ return customRef((track,trigger)=>{ return { get(){ track(); //追踪 告诉vue这个数据是需要追踪的 return value }, set(newValue){ value=newValue trigger(); //触发 告诉vue触发界面更新 } } }) }
- 获取元素ref 在vue3中也可以通过ref来获取元素(mounted 最早能获取到页面元素)
- readonly只读 用于创建一个只读的数据,并且是递归只读
- isReadonly 是否是readonly
- shallowReadonly浅只读的 用于创建一个只读第一层的数据
注意:const和readonly区别
const:赋值保护,不能给变量重新赋值
readonly:属性保护,不能给属性重新赋值
三、vue3响应式数据本质
1.
在vue2中是通过defineProperty来实现响应式数据的
在vue3中是通过Proxy来实现响应式数据的
注意:定义Proxy代理对象的set的时候,要返回 return true,通过返回值告诉Proxy此次操作是否成功
let state =new Proxy(arr, {
get(obj,key){
return obj[key]
},
set(obj,key,value){
//数组两步操作,先追加值,再添加数组长度
// [ 2, 4, 6 ] 3 8
// [ 2, 4, 6, 8 ] length 4
obj[key]=value
console.log('更新UI界面')
return true
}
})
state.push(8)
2.手写ref和reactive
function ref(val){
return reactive({value:val})
}
function reactive(obj){
// reactive 把每一层都包装成Proxy
if(typeof obj==="object"){
if(obj instanceof Array){
obj.forEach((item,index)=>{
if(typeof item === "object"){
obj[index] = reactive(item)
}
})
}else{
for(let key in obj){
let item =obj[key]
if(typeof item === 'object'){
obj[key]=reactive(item)
}
}
}
//包装成Proxy对象
return new Proxy(obj,{
get(obj,key){
return obj[key]
},
set(obj,key,val){
obj[key]=val
console.log('触发更新')
return true
}
})
}else{
console.warn(`${obj} is not object`);
}
}
let arr = [{id:1,name:"鲁班"},{id:2,name:"虞姬"},{id:3,name:'007'}]
let state = reactive(arr)
state[0].name='zs'
state[1].name='muzi'