欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

学习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

  1. reactive本质:就是将传入的数据包装成一个Proxy对象
  2. ref本质:包装成一个带value的属性传入reactive ref(666) -> reactive({value:666})
    注意:ref和reactive都是递归监听(如果数据量比较大,非常消耗性能)
  3. shallowReactive只监听第一层的变化
  4. shallowRef监听的是.value的变化,并不是第一层的变化 (因为底层本质上value才是第一层)
  5. triggerRef触发界面更新 (ref数据类型)
    注意:vue3没有提供triggerReactive方法,所以reactive类型的数据无法主动触发界面更新
  6. toRaw返回reactive或readonly代理的原始对象
  7. markRaw标记一个对象,使其永远不会转换为proxy。返回对象本身
  8. toRef
    toRef->引用 修改响应式数据会影响到以前的数据,且数据发生改变,界面不会自动更新
    ref->复制 修改数据不会影响到以前的数据且界面会自动更新
  9. customRef 自定义一个ref
    function myRef(value){
      return customRef((track,trigger)=>{
        return {
          get(){
            track();  //追踪 告诉vue这个数据是需要追踪的
            return value
          },
          set(newValue){
            value=newValue
            trigger();  //触发 告诉vue触发界面更新
          }
        }
      })
    }
    
  10. 获取元素ref 在vue3中也可以通过ref来获取元素(mounted 最早能获取到页面元素)
  11. readonly只读 用于创建一个只读的数据,并且是递归只读
  12. isReadonly 是否是readonly
  13. 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'