vue3新增知识点(组合式API、ref和reactive、响应式原理、setup、watch和watchEffect)持续更新

1.组合式API和声明式API的区别,组合式API的优点

2.Vue3的响应式原理
通过Proxy(代理):拦截对象中任意属性的变化:包括:属性值的读写、属性的添加、属性的删除等。
通过reflect(反射):对被代理对象的属性进行操作

    let person={
        name:'张三',
        age:18
    }
    let p=new Proxy(person,{
        get(target,propname){
            console.log(`请求获取p(${target})中的${propname}`);
            // return target[propname]
            return Reflect.get(target,propname)

        },
        set(target,propname,value){
            console.log(`修改p(${target})中的${propname}`);
            // target[propname]=value
            Reflect.set(target,propname,value)
        },
        delete(target,propname){
            console.log(`删除p(${target})中的${propname}`);
            // return delete target[propname]
            return Reflect.defineProperty(target,propname)
        }

    })

3.ref和reactive
对比:
从定义角度:
ref用来定义:基本类型数据
reactive用来定义:对象和数组类型数据
备注:ref也可以用啦定义对象和数组类型的数据,它内部会自动通过reactive转为代理对象

从原理角度对比:
ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)
reactive通过使用Proxy来实现响应式(数据劫持),并通过Reflect来操作源对象的内部数据

从使用角度:
ref定义的数据:操作数据需要.value,读取数据时模版中直接读取不需要value
reactive:操作数据与读取数据:均不需要.value

ref用来处理基本数据类型也可以处理对象类型,在处理数据时,例如修改数据需要在变量后面加上value,
使用ref

<script setup>
import { ref, reactive } from 'vue'
let name=ref('jack')
let age=ref(18)
let item=ref({
    job:'前端开发工程师',
    salary:'50k'
})
function increment(){
     name.value='jonh',
     age.value=118,
     item.value.job='UI'

}
</script>
<template>
 <div>
     <h1>一个人的信息</h1>
     <h2>姓名:{{name}}</h2>
     <h2>年龄:{{age}}</h2>
     <h2>职业:{{item.job}}</h2>
     <h2>薪水:{{item.salary}}</h2>
     <button @click="increment">修改个人信息</button>
 </div>
</template>

处理对象类型和数组类型的数据时,使用reactive,不建议使用reactive处理基本数据类型
使用reactive之后,就不需要通过加上value来改变原先的值

<script setup>
import { ref, reactive } from 'vue'
let name=ref('jack')
let age=ref(18)
let item=reactive({
    job:'前端开发工程师',
    salary:'50k'
})
function increment(){
     name.value='jonh',
     age.value=118,
     item.job='UI'

}
</script>

3.setup的两个注意点
setup的执行时机
在beforeCreate之前执行一次,this是undefined,所在在setup中是不能使用this的因为
什么都获取不到

setup参数
props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性
context:上下文对象
attrs:值为对象,包含:组件外部传递过来的,但是没有在props配置中声明的属 性,相对应this.$attrs.
slots:收到的插槽内容,相对应this.$solts.
emit:分发自定义事件的函数,相当于this.$emit.

4.computed函数、

    setup(){
        let firstName=ref('')
        let lastName=ref('')
        // let fullName=computed(()=>{
        //     return firstName.value+'-'+lastName.value
        // })
        let fullName=computed({
            get(){
                return firstName.value+'-'+lastName.value
            },
            set(value){
                let nameArr=value.split('-')
                firstName.value=nameArr[0]
                lastName.value=nameArr[1]
            }
        })
        return {
            firstName,
            lastName,
            fullName
        }
    }


5.watch
情况一:监听ref所定义的一个响应式数据

 //情况一:监听ref所定义的一个响应式数据
        watch(sum,(oldValue,newValue)=>{
            console.log('监听到了改变',oldValue,newValue);
        })

情况二:监听ref所定义的多个响应式数据

 watch([sum,msg],(newValue,oldValue)=>{
            console.log('sum or msg 变化了',newValue,oldValue);
        })

情况三:监听reactive所定义的一个响应式数据
1.注意:此处无法正确获取oldValue
2.注意:强制开启了深度监视(deep配置无效)

        watch(person.value,(newValue,oldValue)=>{
            console.log('person变化了',newValue,oldValue);
        })

情况四:监听reactive所定义的一个响应式数据中的某个属性

        watch(()=>person.name,(newValue,oldValue)=>{
            console.log('person的name变化了',newValue,oldValue);
        })

情况五:监视reactive所定义的一个响应式数据中的某些属性

        watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
            console.log('person的name和age变化了',newValue,oldValue);
        })

特殊情况:使用deep监听深层数据的变化 (此处因为监听的是reactive中的对象中的某个属性依然是个对象,所以deep配置有效)
watchEffect
watch的套路:既要指明监听的属性,也要指明监视的回掉
watchEffect的套路是:不用指明监视的哪个属性,监视的回调中用到哪个属性,那就监视哪个属性
watchEffect有点像computed
但computed注重计算的出来的值(回调函数的返回值),所以必须要写返回值
而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值

watchPostEffect
watchProxyEffect

6.render函数
render函数使得我们使用js构建dom
当使用精简版vue库的时候,没有模版解析器,那怎么构建dom呢,这个时候需要使用render函数,将模版template解析成js文件从而构建虚拟dom,就省去了vue转译的过程,
其实都是将模版解析为虚拟dom树
当使用完整版的vue库的时候,含有模版解析器,模版解析占用vue库大概三分之一的空间,在webpack打包的时候,模版解析器一直在,其实,使用精简版vue旨在减少打包的内存

posted @ 2022-12-02 15:14  终究还是避免不了遗憾  阅读(369)  评论(1编辑  收藏  举报