日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs

發布時間:2023/12/4 vue 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一文了解Composition API新特性:ref、toRef、toRefs

  • 一、🙎如何理解ref、toRef和toRefs
    • 1、ref、toRef和toRefs是什么
      • (1)ref
        • 1)ref是什么
        • 2)舉個例子🌰
      • (2)toRef是什么
        • 1)toRef是什么
        • 2)舉個例子🌰
      • (3)toRefs是什么
        • 1)toRefs是什么
        • 2)舉個例子🌰
      • (4)合成函數返回響應式對象
    • 2、最佳使用方式
    • 3、深入理解
      • (1)為什么需要用ref
      • (2)為何ref需要.value屬性
      • (3)為什么需要toRef和toRefs
  • 二、🙆?♀?Composition API實現邏輯復用
    • 1、規則
    • 2、舉個例子🌰
  • 三、🙅?♀?結束語

在 上一篇文章中,我們初步了解了vue3的新特性,今天,我們將延續 Composition API的話題,來了解 Composition API帶來的新特性: ref 、 toRef 和 toRefs 。

下面開始進入本文的講解?

一、🙎如何理解ref、toRef和toRefs

1、ref、toRef和toRefs是什么

(1)ref

1)ref是什么

  • ref 可以生成 值類型(即基本數據類型) 的響應式數據;
  • ref 可以用于模板reative
  • ref 通過 .value 來修改值(一定要記得加上 .value );
  • ref 不僅可以用于響應式,還可以用于模板的 DOM 元素。

2)舉個例子🌰

假設我們定義了兩個值類型的數據,并通過一個定時器來看它響應式前后的效果。接下來我們用代碼來演示一下:

<template><p>ref demo {{ageRef}} {{state.name}}</p> </template><script> import { ref, reactive } from 'vue'export default {name: 'Ref',setup(){const ageRef = ref(18)const nameRef = ref('monday')const state = reactive({name: nameRef})setTimeout(() => {console.log('ageRef', ageRef.value,'nameRef', nameRef.value)ageRef.value = 20nameRef.value = 'mondaylab'console.log('ageRef', ageRef.value,'nameRef', nameRef.value)},1500)return{ageRef,state}} } </script>

別眨眼,來看下此時瀏覽器的顯示效果:

大家可以看到,控制臺先后打印的順序是響應式前的數據響應式后的數據。因此,通過 ref ,可以實現值類型的數據響應式。


值得注意的是, ref 不僅可以實現響應式,還可以用于模板的DOM元素我們用一段代碼來演示一下:

<template><p ref="elemRef">今天是周一</p> </template><script> import { ref, onMounted } from 'vue'export default {name: 'RefTemplate',setup(){const elemRef = ref(null)onMounted(() => {console.log('ref template', elemRef.value.innerHTML, elemRef.value)})return{elemRef}} } </script>

此時瀏覽器的顯示效果如下所示:

我們通過在模板中綁定一個 ref ,之后在生命周期中調用,最后瀏覽器顯示出該 DOM 元素。所以說, ref 也可以用來渲染模板中的DOM元素。

(2)toRef是什么

1)toRef是什么

  • toRef 可以響應對象 Object ,其針對的是某一個響應式對象( reactive 封裝)的屬性prop 。

  • toRef 和對象 Object 兩者保持引用關系,即一個改完另外一個也跟著改。

  • toRef 如果用于普通對象(非響應式對象),產出的結果不具備響應式。如下代碼所示:

//普通對象 const state = {age: 20,name: 'monday' } //響應式對象 const state = reactive({age: 20,name: 'monday' })

2)舉個例子🌰

對于一個普通對象來說,如果這個普通對象要實現響應式,就用 reactive 。用了 reactive 之后,它就在響應式對象里面。那么在 一個響應式對象里面,如果其中有一個屬性要拿出來單獨做響應式的話,就用 toRef 。來舉個例子看一看:

<template><p>toRef demo - {{ageRef}} - {{state.name}} {{state.age}}</p> </template><script> import { ref, toRef, reactive, computed } from 'vue'export default {name: 'ToRef',setup() {const state = reactive({age: 18,name: 'monday'})// // toRef 如果用于普通對象(非響應式對象),產出的結果不具備響應式// const state = {// age: 18,// name: 'monday'// }//實現某一個屬性的數據響應式const ageRef = toRef(state, 'age')setTimeout(() => {state.age = 20}, 1500)setTimeout(() => {ageRef.value = 25 // .value 修改值}, 3000)return {state,ageRef}} } </script>

此時我們來看下瀏覽器的顯示效果:

我們通過 reactive 來創建一個響應式對象,之后呢,如果只單獨要對響應式對象里面的某一個屬性進行響應式,那么使用toRef 來解決。用 toRef(Object, prop) 的形式來傳對象名具體的屬性名,達到某個屬性數據響應式的效果。

(3)toRefs是什么

1)toRefs是什么

  • 與 toRef 不一樣的是, toRefs 是針對整個對象的所有屬性,目標在于將響應式對象( reactive 封裝)轉換為普通對象
  • 普通對象里的每一個屬性 prop 都對應一個 ref
  • toRefs 和對象 Object 兩者保持引用關系,即一個改完另外一個也跟著改。

2)舉個例子🌰

假設我們要將一個響應式對象里面的所有元素取出來,那么我們可以這么處理。代碼如下:

<template><p>toRefs demo {{state.age}} {{state.name}}</p> </template><script> import { ref, toRef, toRefs, reactive } from 'vue'export default {name: 'ToRefs',setup() {const state = reactive({age: 20,name: 'monday'})return {state}} } </script>

此時瀏覽器的顯示結果如下:

但是這樣子好像有點略顯麻煩,因為在模板編譯的時候一直要 state. ,這樣如果遇到要取很多個屬性的時候就有點臃腫了。


既然太臃腫了,那我們換一種思路,把 state 進行解構。代碼如下:

<template><p>toRefs demo {{age}} {{name}}</p> </template><script> import { ref, toRef, toRefs, reactive } from 'vue'export default {name: 'ToRefs',setup() {const state = reactive({age: 20,name: 'monday'})return {...state}} } </script>

此時瀏覽器的顯示結果如下:

效果是一樣的,看起來清晰了很多。但是呢……天上總不會有無緣無故的餡餅出現,得到一些好處的同時總要失去些原本擁有的東西。


對于解構后的對象來說,如果直接解構 reactive ,那么解構出來的對象會直接失去響應式。我們用一個定時器來檢驗下效果,具體代碼如下:

<template><p>toRefs demo {{age}} {{name}}</p> </template><script> import { ref, toRef, toRefs, reactive } from 'vue'export default {name: 'ToRefs',setup() {const state = reactive({age: 20,name: 'monday'})setTimeout(() => {state.age = 25}, 1500)return {...state}} } </script>

此時瀏覽器的顯示結果如下:

我們等了好幾秒之后,發現 age 遲遲不變成25,所以當我們解構 reactive 的對象時,響應式將會直接失去。


所以,就來到了我們的 toRefs 。 toRefs 在把響應式對象轉變為普通對象后,不會丟失掉響應式的功能。具體我們用代碼來演示一下:

<template><p>toRefs demo {{age}} {{name}}</p> </template><script> import { ref, toRef, toRefs, reactive } from 'vue'export default {name: 'ToRefs',setup() {const state = reactive({age: 18,name: 'monday'})const stateAsRefs = toRefs(state) // 將響應式對象,變成普通對象setTimeout(() => {console.log('age', state.age, 'name', state.name)state.age = 20,state.name = '周一'console.log('age', state.age, 'name', state.name)}, 1500)return stateAsRefs} } </script>

此時我們觀察瀏覽器的顯示效果:

大家可以看到,用了 toRefs ,普通對象的值成功被取出來了,并且還不會丟失響應式的功能,該改變的值一個也不少。

(4)合成函數返回響應式對象

了解了上面三種類型的使用,我們再來看一種場景:合成函數如何返回響應式對象下面附上代碼:

function useFeatureX(){ const state = reactive({ x: 1, y: 2 }) //邏輯運行狀態,…… //返回時轉換為ref return toRefs(state) } export default{ setup(){ //可以在不失去響應性的情況下破壞結構 const {x, y} = useFeatureX() return{ x, y } }}

在第一段代碼中,我們定義了一個函數,并且用 toRefs 將 state 對象進行返回,之后在組件里面直接調用響應式對象。

通過這樣方式,讓代碼邏輯變得更加清晰明了,復用性更強。

2、最佳使用方式

通過上面的演示可以得出以下幾點結論:

  • 用 reactive 做對象的響應式,用 ref 做值類型的響應式。
  • setup 中返回 toRefs(state) ,或者 toRef(state, 'xxx') 。
  • 為了防止誤會產生, ref 的變量命名盡量都用 xxxRef ,這樣在使用的時候會更清楚明了。
  • 合成函數返回響應式對象時,使用 toRefs

3、深入理解

講完 ref 、 toRef 和 toRefs ,我們再來思考一個問題:為什么一定要用它們呢?可以不用嗎?

(1)為什么需要用ref

  • 值類型(即基本數據類型)無處不在,如果不用 ref 而直接返回值類型,會丟失響應式。
  • 比如在 setup 、 computed 、合成函數等各種場景中,都有可能返回值類型。
  • Vue 如果不定義 ref ,用戶將自己制造 ref ,這樣反而會更加混亂。

(2)為何ref需要.value屬性

通過上面的分析我們知道, ref 需要通過 .value 來修改值。這看起來是一個很麻煩的操作,總是頻繁的 .value 感覺特別瑣碎。那為什么一定要 .value 呢?我們來揭開它的面紗。

  • ref 是一個對象,這個對象不丟失響應式,且這個對象用 value 來存儲值。
  • 因此,通過 .value 屬性的 get 和 set 來實現響應式。
  • 只有當用于 模板reactive 時,不需要 .value 來實現響應式,而其他情況則都需要。

(3)為什么需要toRef和toRefs

與 ref 不一樣的是, toRef 和 toRefs 這兩個兄弟,它們不創造響應式,而是延續響應式。創造響應式一般由 ref 或者 reactive 來解決,而 toRef 和 toRefs 則是把對象的數據進行分解和擴散,其這個對象針對的是響應式對象非普通對象。總結起來有以下三點:

  • 初衷:不丟失響應式的情況下,把對象數據進行 分解或擴散
  • 前提: 針對的是響應式對象( reactrive 封裝的)而非普通對象
  • 注意: 不創造響應式,而是延續響應式。

二、🙆?♀?Composition API實現邏輯復用

1、規則

先來了解幾條規則:

  • Composition API 指抽離邏輯代碼到一個函數
  • 函數的命名約定為 useXxxx 格式(React hooks也是);
  • 在 setup 中引用 useXxx 函數。

2、舉個例子🌰

引用一個非常經典的例子:獲取鼠標的定位。接下來我們用Composition API來進行封裝演示:

定義一個 js 文件,名字為 useMousePosition ,具體代碼如下:

import { reactive, ref, onMounted, onUnmounted } from 'vue'function useMousePosition() {const x = ref(0)const y = ref(0)function update(e) {x.value = e.pageXy.value = e.pageY}onMounted(() => {console.log('useMousePosition mounted')window.addEventListener('mousemove', update)})onUnmounted(() => {console.log('useMousePosition unMounted')window.removeEventListener('mousemove', update)})return {x,y} }

再定義一個 .vue 文件,命名為 index.vue 。具體代碼如下:

<template><p v-if="flag">mouse position {{x}} {{y}}</p><button @click="changeFlagHandler">change flag</button> </template><script> import { reactive } from 'vue' import useMousePosition from './useMousePosition'export default {name: 'MousePosition',return {flag: true},setup() {const { x, y } = useMousePosition()return {x,y}}changeFlagHandler() {this.flag = !this.flag}, } </script>

此時瀏覽器的顯示效果如下:

了解完 ref 后,我們來實現這個功能看起來會清晰很多。我們先通過 ref 對 x 和 y 做響應式操作,之后通過 .value 來修改值,最終達到時刻獲取鼠標定位的效果。同時,如果我們時刻保持著鼠標移動時不斷改變值,這樣子是非常耗費性能的。所以,我們可以通過一個按鈕,來隨時控制它的出現與隱藏。

大家可以發現,當隱藏的時候,隨后會觸發 onUnmounted 生命周期組件內容隨之被銷毀。也就是說,使用的時候調用,不使用的時候及時銷毀,這樣子可以很大程度上提升性能。

三、🙅?♀?結束語

通過上文的學習,我們可以知道, ref 、 toRef 和 toRefs 是 vue3 中 Composition API 的新特性,且 vue3 一般通過 ref 、 toRef 和 toRefs 來實現數據響應式。有了這三個內容,實現數據響應式看起來方便許多,而不再像 vue2 中那種處理起來很困難。

到這里,關于 ref 、 toRef 和 toRefs 的內容就講完啦!希望對大家有幫助!

如有疑問或文章有誤歡迎評論區瀏覽或私信我交流~

  • 關注公眾號 星期一研究室 ,第一時間關注學習干貨,更多有趣的專欄待你解鎖~
  • 如果這篇文章對你有用,記得 一鍵三連 再走哦!
  • 我們下期見!🥂🥂🥂

總結

以上是生活随笔為你收集整理的敲黑板!vue3重点!一文了解Composition API新特性:ref、toRef、toRefs的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产精品久久久久久免费免熟 | 色丁香综合 | 日韩在线免费视频观看 | 蜜桃av噜噜一区二区三区 | 成人夜色 | 精品一区二区在线免费观看 | 看片久久 | aaa天堂 | 久久久影视 | 精品中文字幕在线观看 | 热99精品| 中文字幕一区二区三区四区五区 | 免费在线观看日韩 | 国产日产久久高清欧美一区 | 人人干夜夜操 | 亲切的金子片段 | 黄色a级片网站 | 日韩福利在线 | 国产精品自拍在线 | 国产一区二区在线免费观看 | 亚洲激情自拍偷拍 | 国产原创视频在线 | 久久先锋 | 91麻豆产精品久久久久久夏晴子 | 婷婷激情综合网 | 国产精品国产三级国产aⅴ9色 | 国产对白羞辱绿帽vk | 亚洲人人爱 | 警察高h荡肉呻吟男男 | 亚洲性图一区二区 | 国产99热 | 黑人100部av解禁片 | 精品国产一区二区三区噜噜噜 | 五月婷婷六月色 | 亚洲手机在线 | 隔壁邻居是巨爆乳寡妇 | 岛国大片在线免费观看 | 国产精品黄色在线观看 | 在线观看国产麻豆 | 国产一级在线播放 | 欧美色图首页 | 日韩一级黄色录像 | 亚洲精品99久久久久中文字幕 | 中文字幕日本在线 | 日本黄色一区二区 | 亚洲午夜久久久久久久久久久 | 亚洲大成色 | 免费日韩视频 | 精品国产a线一区二区三区东京热 | 国产免费又黄又爽又色毛 | 91免费网址 | 69视频一区二区 | 成人一区二区在线观看 | 天天综合网永久 | 91深夜福利 | 黄色视屏在线看 | 日韩经典一区二区三区 | 精品久久久久一区二区国产 | 加勒比成人在线 | 91色拍| 秋霞网一区二区三区 | 丁香婷婷色 | 国产免费无遮挡吸奶头视频 | 久久a久久 | 视频在线观看99 | 色婷婷激情五月 | 欧美色图亚洲自拍 | 噜噜色综合 | 不卡av影院 | 亚洲免费在线视频观看 | av合集| 青青草在线免费 | 香蕉网在线 | 欧美xxxxxx片免费播放软件 | 免费在线中文字幕 | www.com黄色片| 艳妇臀荡乳欲伦交换在线看 | 免费黄色入口 | 熟女毛毛多熟妇人妻aⅴ在线毛片 | 91ts人妖另类精品系列 | 91精品推荐 | 欧美一区中文字幕 | 国产精品国产三级国产aⅴ中文 | 日本男男激情gay办公室 | 思思精品视频 | 欧美福利电影 | 成人av免费 | 视色在线 | 欧美一区二区三区精品 | 亚洲第一页在线观看 | 电影一区二区三区 | 国模视频一区二区 | 精品一区二区在线视频 | 亚州精品视频 | 久久久亚洲成人 | 国产精品一区免费观看 | 欧美一区二区三区久久精品 | 久草资源在线观看 | av青草|