13518219792

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

一网打尽──Vue3Composition-api新特性

写在前面

在体验Vue3之前,我们先来了解一下Vu3到底有哪些亮点之处。

创新互联成立于2013年,是专业互联网技术服务公司,拥有项目网站建设、网站制作网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元高港做网站,已为上家服务,为高港各地企业和个人服务,联系电话:18980820575

总共有6大特点:

一、vue3的起源setup

1.理解:vue3.0的组合api舞台是setup

2.setup所有的数据方法等都配置在setup中

3.setup有两种返回值:

4.注意:

5.setup不能是一个async函数,因为返回值不再是return的对象,而是promise,模板看不到return对象中的属性(后期也可以使用suspense和异步组件的配合得到promise)

二、ref函数

作用:用于定义一个响应式数据

语法:const name = ref(initValue)

注意:

三、reactive函数

ref和reactive的差异

reactive就是用于将对象数据转为响应式,与vue2的observable类似,而ref用于获得单独或为基础数据类型转为响应式。

为什么在vue3中会有两个将数据转为响应式数据的api,我们来进行详细说明:

简而言之,reactive可以将对象数据转为响应式,可以将对象中的每个元素都转为ref响应式数据;而ref不仅可以将对象数据转为响应式,还可以处理基础数据类型(string、boolean等)。

之所以会有此差异,那时因为vue3中的响应式是基于proxy实现的,而对于proxy的target必须是引用数据类型,即存放在堆内存中通过指针进行引用的对象。为什么是代理的引用数据类型,那是因为简单数据类型每次赋值都是全新的数据,根本无法进行代理,因此难以实现简单数据类型的响应式。

如果我们想要获取简单数据类型的响应式,应该如何做呢?

vue3中也考虑到这点,可以通过ref进行简单数据类型的响应式处理。ref通过创建内部状态,将值挂到value上,因此ref生成的对象要通过.value获取使用。而重写get/set获得的监听,同时对对象的处理也依赖了reactive的实现。

正是如此,ref既可以处理简单数据类型,又可以将引用数据类型进行响应式处理。在实践中,我们应该避免将reactive当作vue2的data在顶部将所有变量进行声明,而是应该结合具体的应用和逻辑进行就近声明。

 
 
 
 
  1. class RefImpl { 
  2.   private _value: T 
  3.  
  4.   public readonly __v_isRef = true 
  5.  
  6.   constructor(private _rawValue: T, public readonly _shallow = false) { 
  7.     this._value = _shallow ? _rawValue : convert(_rawValue) 
  8.   } 
  9.  
  10.   get value() { 
  11.     track(toRaw(this), TrackOpTypes.GET, 'value') 
  12.     return this._value 
  13.   } 
  14.  
  15.   set value(newVal) { 
  16.     if (hasChanged(toRaw(newVal), this._rawValue)) { 
  17.       this._rawValue = newVal 
  18.       this._value = this._shallow ? newVal : convert(newVal) 
  19.       trigger(toRaw(this), TriggerOpTypes.SET, 'value', newVal) 
  20.     } 
  21.   } 
  22. ... 
  23. const convert = (val: T): T => 
  24.   isObject(val) ? reactive(val) : val 
  25. ... 

四、Vue3中的响应式原理

vue2的响应式原理:

 
 
 
 
  1. Object.defineProperty(data,"count",{ 
  2.   get(){}, 
  3.   set(){} 
  4. }) 

存在问题:

vue3的响应式原理

五、reactive和ref的差异

定义数据

原理

使用

六、计算属性和监视

与vue2中的computed配置功能一致

写法:

 
 
 
 
  1. import {computed} from "vue"; 
  2. setup(){ 
  3.   const sum = computed(()=>{ 
  4.     return num1 + num2; 
  5.   }) 
 
 
 
 
  1. import {computed,reactive} from "vue" 
  2. setup(){ 
  3.   const person = reactive({ 
  4.     firstName:"wen", 
  5.     lastName:"bo" 
  6.   }) 
  7.   //简写 
  8.   let fullName = computed(()=>{ 
  9.     return person.firstName + "-" + person.lastName; 
  10.   }); 
  11.    
  12.   //完整 
  13.   let fullName = computed(()=>{ 
  14.     get(){ 
  15.       return person.firstName + "-" + person.lastName; 
  16.     }, 
  17.     set(value){ 
  18.       const newArr = value.split("-"); 
  19.       person.firstName = nameArr[0]; 
  20.       person.lastName = nameArr[1]; 
  21.     } 
  22.   }) 

七、watch函数

与vue2中的watch配置功能一致

注意:

 
 
 
 
  1. let person = reactive({ 
  2.   name:"wenbo", 
  3.   age:18, 
  4.   job:{ 
  5.     job1:{ 
  6.       salary:20 
  7.     } 
  8.   } 
  9. }) 
  10.  
  11. // 情况一:监视ref定义的响应式数据 
  12. watch(sum,(newValue,oldValue)=>{ 
  13.   console.log("sum变了",newValue,oldValue); 
  14. },{immediate:true}) 
  15.  
  16. // 情况二:监视多个ref定义的响应式数据 
  17. watch([sum,msg],(newValue,oldValue)=>{ 
  18.   console.log("sum或msg变了",newValue,oldValue); 
  19. }) 
  20.  
  21. /*情况三:监视reactive定义的响应式数据 
  22.   若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue 
  23.   若watch监视的是reactive定义的响应式数据,则强制开启了深度监视 
  24.   此时的deep不生效 
  25. */ 
  26. watch(person,(newValue,oldValue)=>{ 
  27.   console.log("perosn变了",newValue,oldValue); 
  28. },{immediate:true,deep:false}) 
  29.  
  30. //情况四:监视reactive所定义的一个响应式数据中的某个属性 
  31. watch(()=>person.age,(newValue,oldValue)=>{ 
  32.   console.log("person的age变化了",newValue,oldValue) 
  33. }) 
  34.  
  35. //情况五:监视reactive所定义的一个响应式数据中的某些属性 
  36. watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{ 
  37.   console.log("person的name或age变化了",newValue,oldValue) 
  38. }) 
  39.  
  40. //特殊情况-监听的对象的属性还是个对象,此时deep生效,可以进行深度监听 
  41. watch(()=>person.job,(newValue,oldValue)=>{ 
  42.   console.log("person的job变化了",newValue,oldValue) 
  43. },{deep:true}) 

注意:

watch监听reactive定义的对象有五种情况

watch监听ref定义的响应式数据有两种情况:

八、watchEffect函数

watch的套路:既要指明监视的属性,又要指明监视的回调

watchEffect的套路:不用指明监视的哪个属性,监视的回调中用到哪个属性,就监视哪个属性

watchEffect有点类似computed:

 
 
 
 
  1. let person = reactive({ 
  2.   name:"wenbo", 
  3.   age:18, 
  4.   job:{ 
  5.     job1:{ 
  6.       salary:20 
  7.     } 
  8.   } 
  9. }) 
  10.  
  11. // warchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调 
  12. watchEffect(()=>{ 
  13.   const x = person.name 
  14.   const y = person.job.job1.salary 
  15.   console.log("watchEffect触发了") 
  16. }) 

九、自定义hooks函数

  
 
 
 
  1. pageX:{{point.pageX}},pageY:{{point.pageY}}
     

hooks文件 usePoint.js

   
 
 
 
  1. import {reactive} from "vue" 
  2.  
  3. const handleClickPoint = ()=>{ 
  4.   //实现鼠标“打点”相关数据 
  5.   let point = reactive({ 
  6.     pageX:0, 
  7.     pagey:0 
  8.   }) 
  9.    
  10.   //实现鼠标“打点”相关方法 
  11.   const handlePoint = (event)=>{ 
  12.     point.pageX = event.pageX; 
  13.     point.pageY = event.pageY; 
  14.     console.log(event.pageX,event.pageY) 
  15.   } 
  16.   //实现鼠标打点的相关周期函数 
  17.   onMounted(()=>{ 
  18.     window.addEventListener("click",handlePoint) 
  19.   }) 
  20.    
  21.   onBeforeUnmounted(()=>{ 
  22.     window.removeEventListener("click",handlePoint) 
  23.   }) 

十、toRef函数

十一、VUE3生命周期

其它组合式api

1. shallowReactive与shallowRef

shallowReactive:只处理对象最外层属性的响应式(浅响应式)

shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理

使用时机:

2. readonly与shallowReadonly

3. toRaw与markRaw

toRaw

markRaw

4. customRef

作用:创建一个自定义ref,并对其依赖项跟踪和更新触发进行显式控制

示例:

   
 
 
 
  1.  
  2.  
  3.    

5. provide与inject

6. 响应式数据的判断

vue3中使用hook注意点

hook中存在异步问题

其实在使用中可以发现,其实hook本质上就是进行抽取的函数,灵活性比较高,但是在涉及到异步逻辑时考虑不周全就会导致很多问题。hook是可以覆盖异步情况的,但是必HTML须在setup当中执行时返回有效对象不能被阻塞。

通常异步具有两种风格:

外部没有其它依赖,只是交付渲染的响应变量。对于此种情况,可以通过声明、对外暴露响应变量,在hook中使用异步修改的方式。

外部具有依赖,需要在使用侧进行加工。对于此种情形,可以通过对外暴露Promise的方式,使得外部获取到同步操作的能力。

this的问题

由于setup处于生命周期的beforeCreate和created阶段之间,因此不能获取到this。当然我们可以通过setup的第二个参数context获取到类似与this的部分能力,但是对于想操作路由、vuex等能力则受到了限制,为此最新的router@4、vuex@4都提供了组合式的api。

由于vue2底层限制使得无法使用这些hook,为此可以通过引用实例的方式获取一定的操作能力,也可以通过getCurrentInstance获得组件实例上挂载的对象。

虽然组合式api的响应式原理是通过Object.defineProperty改写属性的,与vue的响应式原理相同,但是在具体实现方式上存在差异,因此在setup中与vue原生的响应式并不互通。正因此,导致即使拿到相应的实例也没有办法监听它们的响应式,只能通过在选项配置进行使用。

vue3中常见的组件

1. Fragment组件

在vue2中:组件必须有一个根标签

在vue3中:组件可以没有根标签,内部会将多个标签包裹在Fragment虚拟元素中

好处:减少标签层级,减少内存占用

2. Teleport

Teleport时倚重能够将组件html结构移动到指定位置的技术

语法:

main.vue

   
 
 
 
 
  •  
  • open modal 
  • modal.vue

        
     
     
     
    1.  
    2.     
    3.      this is a modal 
    4.      close 
    5.    
     
  •   
  • 3. suspense

    等待异步组件时渲染一些额外内容,让应用有更好的用户体验。

    使用步骤:

        
     
     
     
    1. import {defineAsyncComponent} from "vue" 
    2. const child =defineAsyncComponent(()=>import("./components/child.vue")) 

    【编辑推荐】

    1. 鸿蒙官方战略合作共建——HarmonyOS技术社区
    2. 云中的容器:你有哪些选择?
    3. 5G消息全力迈入发展期
    4. 什么是域名劫持?遇到域名劫持要怎么处理
    5. 自学编程,到底先选什么语言?
    6. 一文看完网络爬虫发展史

    文章标题:一网打尽──Vue3Composition-api新特性
    文章地址:http://cdbrznjsb.com/article/djjeges.html

    其他资讯

    让你的专属顾问为你服务