欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue組合式API--setup中定義響應(yīng)式數(shù)據(jù)的示例詳解

 更新時(shí)間:2022年10月09日 10:54:57   作者:流水武qin  
在Vue2.x中,編寫組件的方式是使用Options API,它的特點(diǎn)是在對應(yīng)的屬性中編寫對應(yīng)的功能模塊,這篇文章主要介紹了Vue組合式API--setup中定義響應(yīng)式數(shù)據(jù)詳解,需要的朋友可以參考下

一、Options API(選項(xiàng)式API)的弊端

1.1 什么是選項(xiàng)式API

Vue2.x中,編寫組件的方式是使用Options API,它的特點(diǎn)是在對應(yīng)的屬性中編寫對應(yīng)的功能模塊。

比如data中定義數(shù)據(jù)、methods中定義方法、computed中定義計(jì)算屬性、watch中監(jiān)聽屬性改變。

生命周期鉤子也屬于Options API(選項(xiàng)式API)。

1.2 選項(xiàng)式API的弊端

  • 當(dāng)我們實(shí)現(xiàn)某一個(gè)功能時(shí),這個(gè)功能對應(yīng)的代碼邏輯會(huì)被拆分到各個(gè)屬性中。

當(dāng)組件變得很大、很復(fù)雜時(shí),邏輯關(guān)注點(diǎn)的列表就會(huì)增長,那么同一個(gè)功能的邏輯就會(huì)被拆分的很分散。

特別是對于那些一開始沒有編寫這些組件的人(閱讀組件的人)來說,這個(gè)組件的代碼是難以閱讀和理解的。

  • 碎片化的代碼使用理解和維護(hù)這個(gè)復(fù)雜的組件變得非常困難,很容易隱藏了潛在的邏輯問題。
  • 當(dāng)處理單個(gè)邏輯關(guān)注點(diǎn)時(shí),需要不斷的跳到相應(yīng)的代碼塊中,增加了代碼維護(hù)的成本。

二、Composition API(組合式API)概述

2.1 Composition API的作用

如果能將同一個(gè)邏輯關(guān)注點(diǎn)相關(guān)的代碼收集在一起會(huì)更好一些,這就是Composition API想 要做的事情。

Vue Composition API可以簡稱為VCA。

2.2 Composition API的編碼位置

Vue3.x提供了setup函數(shù)來編寫各種組合式API

setup其實(shí)也是組件的另外一個(gè)選項(xiàng),只不過這個(gè)選項(xiàng)可以用來替代大部分其他選項(xiàng)式API選項(xiàng)。

比如methods、computed、watch、data、各種生命周期鉤子函數(shù)等等。

三、setup函數(shù)的參數(shù)和返回值

3.1 setup函數(shù)的參數(shù)

setup函數(shù)主要由兩個(gè)參數(shù):

  • props:父組件傳遞過來的屬性會(huì)被放到props對象中
    • props的類型,和選項(xiàng)式API中的的規(guī)則一樣,在props選項(xiàng)中定義
    • props的使用,在template中依然是可以把props中的屬性當(dāng)成普通Vue變量去使用。
    • setup函數(shù)中用props,不可以通過this去獲取
  • context:也稱之為SetupContext,是setup函數(shù)的上下文對象,它主要由三個(gè)屬性
    • attrs:所有的非props的的屬性
    • slots:父組件傳遞過來的插槽,在以渲染函數(shù)返回時(shí)會(huì)有作用
    • emit:當(dāng)組件內(nèi)部需要發(fā)出事件時(shí)會(huì)用到emit
    • 主要是因?yàn)?code>setup函數(shù)中不能訪問this,所以無法通過this.$emit發(fā)出事件

3.2 setup函數(shù)的返回值

setup的返回值可以來替代data選項(xiàng),因此setup的返回值可以在模板template中使用。

<script>
import { ref } from 'vue'

export default {
  setup() {
    // 定義counter的內(nèi)容
    // 默認(rèn)定義的數(shù)據(jù)都不是響應(yīng)式數(shù)據(jù),使用ref可以讓數(shù)據(jù)變成響應(yīng)式的
     let counter = ref(100)
     return {counter}
  }
}
</script>

setup的返回值可以來替代methods中定義的方法

<script>
import { ref } from 'vue'

export default {
  setup() {
    // 定義counter的內(nèi)容
    // 默認(rèn)定義的數(shù)據(jù)都不是響應(yīng)式數(shù)據(jù),使用ref可以讓數(shù)據(jù)變成響應(yīng)式的
    let counter = ref(100)
    const increment = () => {
       counter.value ++
       console.log(counter.value)
    }

	return {counter, increment}

  }
}
</script>

四、setup中如何定義響應(yīng)式數(shù)據(jù)

4.1 reactive函數(shù)

代碼示例:

<template>
  <div>
    <h2>賬號: {{ account.username }}</h2>
    <h2>密碼: {{ account.password }}</h2>
    <!-- 沒使用reactive函數(shù)時(shí),點(diǎn)擊此按鈕,能夠修改數(shù)據(jù),但是卻不能渲染到頁面上 -->
    <button @click="changeAccount">修改賬號</button>
  </div>
</template>
<script>
  // 1.引入reactive函數(shù)
  import { reactive } from 'vue'

  export default {
    setup() {

      // 2.使用reactive函數(shù): 定義復(fù)雜類型的響應(yīng)式數(shù)據(jù)數(shù)據(jù)
      const account = reactive({
        username: "張三",
        password: "666666"
      })
      function changeAccount() {
        account.username = "kobe"
      }
	  // 3.返回定義的數(shù)據(jù)
      return {account, changeAccount}
    }
  }
</script>

由代碼示例可知,使用reactive函數(shù)注意好三步即可:

  • Vue中引入reactive函數(shù)
  • 把要定義的復(fù)雜數(shù)據(jù)類型(對象或者數(shù)組)傳入reactive函數(shù),reactive函數(shù)的返回值就是響應(yīng)式數(shù)據(jù)不要
  • 忘記在setup函數(shù)中返回才可以在模板上使用

為什么加了reactive函數(shù)后數(shù)據(jù)就變成了響應(yīng)式的:

當(dāng)我們使用reactive函數(shù)處理我們的數(shù)據(jù)之后,數(shù)據(jù)再次被使用時(shí)就會(huì)進(jìn)行依賴收集。

當(dāng)數(shù)據(jù)發(fā)生改變時(shí),所有收集到的依賴都是進(jìn)行對應(yīng)的響應(yīng)式操作。

選項(xiàng)式API中的data選項(xiàng)中的復(fù)雜數(shù)據(jù),在底層也是交給了reactive函數(shù)將其編程響應(yīng)式對象的。

4.2 ref函數(shù)

1)ref函數(shù)的基本使用

reactive函數(shù)對傳入的類型是有限制的,它要求必須傳入的是一個(gè)對象或者數(shù)組類型。

如果傳入一個(gè)基本數(shù)據(jù)類型,比如String、NumberBoolean等等就會(huì)報(bào)出一個(gè)警告:

value cannot be made reactive : xxx

Vue3給我們提供了另外一個(gè)ref函數(shù)。

ref函數(shù)返回可變的響應(yīng)式對象,該對象作為一個(gè) 響應(yīng)式的引用維護(hù)著它內(nèi)部的值,這也是ref名稱的來源。

它內(nèi)部的值是在refvalue屬性中被維護(hù)的,因此使用ref函數(shù)定義的變量,使用時(shí)需要從value屬性取值。

代碼示例:

<template>
  <div>
    <!-- 默認(rèn)情況下在template中使用ref時(shí), vue會(huì)自動(dòng)對其進(jìn)行解包(取出其中value) -->
    <h2>當(dāng)前計(jì)數(shù): {{ counter }}</h2>
    <button @click="increment">+1</button>
    <button @click="counter++">+1</button>
  </div>
</template>
<script>
  // 1.引入ref函數(shù)
  import { ref } from 'vue'

  export default {
    setup() {

      // 2.ref函數(shù): 主要定義簡單類型的數(shù)據(jù)(也可以定義復(fù)雜類型的數(shù)據(jù))
      const counter = ref(0)
      function increment() {
        counter.value++
      }
	  // 3.返回定義的數(shù)據(jù)
      return {counter, increment}
    }
  }
</script>

2)ref淺層解包

<template>
  <div>
    <!--ref 淺層解包 (意思就是把ref變量放別的對象中時(shí)就會(huì)有下面兩個(gè)情況)-->
    <!-- 使用的時(shí)候不需要寫.value -->
    <h2>當(dāng)前計(jì)數(shù): {{ info.counter }}</h2>
    <!-- 修改的時(shí)候需要寫.value -->
    <button @click="info.counter.value++">+1</button>
  </div>
</template>
<script>
  // 1.引入ref函數(shù)
  import { ref } from 'vue'

  export default {
    setup() {

      // 2.ref函數(shù): 主要定義簡單類型的數(shù)據(jù)(也可以定義復(fù)雜類型的數(shù)據(jù))
      const counter = ref(0)
      const info = {counter}
	  // 3.返回定義的數(shù)據(jù)
      return {counter}
    }
  }
</script>

注意點(diǎn):

  • 在模板中引入ref函數(shù)定義的值時(shí),Vue會(huì)自動(dòng)幫助我們進(jìn)行解包操作
  • 解包就是Vue自動(dòng)取出ref函數(shù)所定義的變量中的value
  • 所以使用者并不需要在模板中通過ref.value 的方式來使用
  • setup函數(shù)內(nèi)部,ref函數(shù)定義的值是一個(gè)ref引用, 所以需要使用ref.value的方式去操作
  • 關(guān)于ref的淺層解包
  • 直接在template中使用ref變量,會(huì)進(jìn)行自動(dòng)解包
  • 如果把ref變量放在一個(gè)對象當(dāng)中會(huì)有下面的情況
    • 使用時(shí),會(huì)進(jìn)行自動(dòng)解包
    • 修改時(shí),不會(huì)進(jìn)行自動(dòng)解包,因此需要使用value屬性去獲取值

4.3 關(guān)于如何選擇reactive函數(shù)和ref函數(shù)

1)選擇reactive函數(shù)的場景

  • reactive函數(shù)應(yīng)用于本地的數(shù)據(jù)的定義,本地?cái)?shù)據(jù)代表這個(gè)數(shù)據(jù)并不是來源于服務(wù)器
  • reactive函數(shù)定義的復(fù)雜數(shù)據(jù)的多個(gè)屬性之間是有一定聯(lián)系的
import {reactive} from 'vue'

const user = reactive({
	username: '張三',
	password: '123456'
})

例如收集一個(gè)表單中的數(shù)據(jù),就是很適合使用reactive函數(shù)的場景

2)選擇ref函數(shù)的場景

定義本地的簡單類型的數(shù)據(jù)

import {ref} from 'vue'

const message = ref('hello ref')

定義從服務(wù)器中獲取的數(shù)據(jù)

import {ref} from 'vue'

const music = ref([])							// 定義一個(gè)本地?cái)?shù)組
const serverMusicList = ['小星星', '蟲兒飛']		// 模擬從服務(wù)器獲取到的數(shù)據(jù)
music.value = serverMusicList					// 把數(shù)據(jù)賦值給music變量

這是經(jīng)驗(yàn)之談,很多優(yōu)秀的開源項(xiàng)目中也都是這么取做的,文檔中并沒有明確說明什么情況使用什么

這其實(shí)也是程序員本身應(yīng)該自己去考慮的問題

五、單向數(shù)據(jù)流和readonly的使用

5.1 單向數(shù)據(jù)流規(guī)范

1)什么是單向數(shù)據(jù)流規(guī)范

父組件傳遞給子組件的對象數(shù)據(jù),子組件只能使用,不允許修改。

雖然是能修改的,但是違反了單向數(shù)據(jù)流的原則。

如果真的想修改這個(gè)數(shù)據(jù),應(yīng)該發(fā)出事件,讓父組件監(jiān)聽這個(gè)事件,然后在父組件中進(jìn)行修改。

2)為什么要遵循這個(gè)原則

今后項(xiàng)目中可能會(huì)有很多子組件,父組件的一個(gè)數(shù)據(jù)可能會(huì)傳遞給多個(gè)子組件。

由于傳遞的是數(shù)據(jù)對象的引用,因此其中一個(gè)子組件中修改了數(shù)據(jù),會(huì)導(dǎo)致全部引用它的地方,全部受到影響。

而且維護(hù)時(shí),難以知道是哪個(gè)位置修改的這個(gè)數(shù)據(jù)。

其它地方也有很多類似的概念規(guī)范:

  • react
  • react有一個(gè)重要的原則:任何一個(gè)組件都應(yīng)該像純函數(shù)一樣,不能修改傳入的props
  • js
  • js中也有類似原則,熟悉js的可能會(huì)知道一個(gè)純函數(shù)的概念。純函數(shù)意思就是函數(shù)不要對傳入的參數(shù)進(jìn)行修改。

這些規(guī)范如果不遵守,代碼確實(shí)也能實(shí)現(xiàn)功能。但是將來維護(hù)性將會(huì)非常差,誰試誰知道。

5.2 readonly的使用

在給組件傳遞數(shù)據(jù)時(shí),如果希望組件使用傳遞的內(nèi)容。但是不允許它們修改時(shí),就可以使用readonly了。

因?yàn)閱蜗驍?shù)據(jù)流原則在Vue2.x的時(shí)候時(shí)沒法從代碼上避免的。如果一個(gè)程序員根本不知道這個(gè)原則。

就有可能寫出難以維護(hù)的代碼。

Vue3.x則提供了readonly函數(shù)從編碼層面去避免這個(gè)問題。

<template>
	<!-- 給組件home傳遞一個(gè)只讀數(shù)據(jù) -->
	<home :info="readonlyInfo" />
</template>
<script>
    import { readonly } from 'vue'
    setup() {
      // 本地定義多個(gè)需要傳遞給子組件的數(shù)據(jù)
      const info = reactive({
        name: "張三",
        age: 25,
        height: 1.78
      })

      // 使用readOnly包裹info
      const roInfo = readonly(info)
      return {roInfo}
    }
</script>

readonly返回的對象都是不允許修改的;但是經(jīng)過readonly處理的原來的對象是允許被修改的。

比如 對于語句const info = readonly(obj)info對象是不允許被修改的。

當(dāng)obj被修改時(shí),readonly返回的info對象也會(huì)被修改;

但是我們不能去修改readonly返回的對象info

如果代碼本身就非常遵守單向數(shù)據(jù)流的原則,那么也可以不使用

readonly的其它注意點(diǎn):

  • readonly會(huì)返回原始對象的只讀代理
  • 也就是它依然是一個(gè)Proxy,這是一個(gè)proxyset方法被劫持,并且不能對其進(jìn)行修改
  • 在開發(fā)中常見的readonly方法會(huì)傳入三個(gè)類型的參數(shù):
  • 類型一:普通對象
  • 類型二:reactive返回的對象
  • 類型三:ref的對象

六、Reactive相關(guān)的判斷的API

  • isProxy:檢查對象是否是由 reactivereadonly創(chuàng)建的 proxy
  • isReactive: 檢查對象是否是由reactive創(chuàng)建的響應(yīng)式代理
  • 如果該代理是 readonly 建的,但包裹了由 reactive 創(chuàng)建的另一個(gè)代理,它也會(huì)返回 true
  • isReadonly:檢查對象是否是由 readonly 創(chuàng)建的只讀代理。
  • toRaw :返回reactivereadonly 代理的原始對象(不建議保留對原始對象的持久引用。請謹(jǐn)慎使用)
  • shallowReactive: 創(chuàng)建一個(gè)響應(yīng)式代理,它跟蹤其自身property的響應(yīng)性

但不執(zhí)行嵌套對象的深層響應(yīng)式轉(zhuǎn)換 (深層還是原生對象)。

shallowReadonly: 創(chuàng)建一個(gè)proxy,使其自身的property為只讀

但不執(zhí)行嵌套對象的深度只讀轉(zhuǎn)換(深層還是可讀、可寫的)

這些用的可能不會(huì)很多,但是也要了解

七、ref其他的API

7.1 toRefs

使用ES6的解構(gòu)語法,對reactive返回的對象進(jìn)行解構(gòu)獲取值,數(shù)據(jù)將不再是響應(yīng)式的。

const info = reactive({
    name: "張三",
    age: 25,
    height: 1.78
})

ES6解構(gòu):

const {name, age, height} = info;

數(shù)據(jù)失去響應(yīng)式

toRefs解構(gòu):

const {name, age, height} = toRefs(info);

解構(gòu)后數(shù)據(jù)仍然保持響應(yīng)式

7.2 unref

用于獲取一個(gè)ref引用中的value。

  • 如果參數(shù)是一個(gè)ref,則返回內(nèi)部值,否則返回參數(shù)本身
  • 這也是 val = isRef(val) ? val.value : val 的語法糖函數(shù) 7.3 isRef

判斷值是否是一個(gè)ref對象。

7.4 shallowRef

創(chuàng)建一個(gè)淺層的ref對象。

7.5 triggerRef

手動(dòng)觸發(fā)和shallowRef創(chuàng)建對象的響應(yīng)式。

到此這篇關(guān)于Vue組合式API--setup中定義響應(yīng)式數(shù)據(jù)詳解的文章就介紹到這了,更多相關(guān)Vue組合式API setup內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue獲取子組件實(shí)例對象ref屬性的方法推薦

    Vue獲取子組件實(shí)例對象ref屬性的方法推薦

    在Vue中我們可以使用ref屬性來獲取子組件的實(shí)例對象,這個(gè)功能非常方便,這篇文章主要給大家介紹了關(guān)于Vue獲取子組件實(shí)例對象ref屬性的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • vue父組件異步獲取數(shù)據(jù)傳給子組件的方法

    vue父組件異步獲取數(shù)據(jù)傳給子組件的方法

    這篇文章主要介紹了vue父組件異步獲取數(shù)據(jù)傳給子組件,需要的朋友可以參考下
    2018-07-07
  • vue2項(xiàng)目使用sass的示例代碼

    vue2項(xiàng)目使用sass的示例代碼

    本篇文章主要介紹了vue項(xiàng)目使用sass的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Vue自定義多選組件使用詳解

    Vue自定義多選組件使用詳解

    這篇文章主要為大家詳細(xì)介紹了Vue自定義多選組件的使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • Vue使用正則校驗(yàn)文本框?yàn)檎麛?shù)

    Vue使用正則校驗(yàn)文本框?yàn)檎麛?shù)

    這篇文章主要介紹了Vue使用正則校驗(yàn)文本框?yàn)檎麛?shù)問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 解決Vue router-link綁定事件不生效的問題

    解決Vue router-link綁定事件不生效的問題

    這篇文章主要介紹了解決Vue router-link綁定事件不生效的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • 基于vue的換膚功能的示例代碼

    基于vue的換膚功能的示例代碼

    本篇文章主要介紹了基于vue的換膚功能的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • vue中checkbox如何修改為圓形樣式

    vue中checkbox如何修改為圓形樣式

    這篇文章主要介紹了vue中checkbox如何修改為圓形樣式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • vue?iview封裝模態(tài)框的方法

    vue?iview封裝模態(tài)框的方法

    這篇文章主要為大家詳細(xì)介紹了vue?iview封裝模態(tài)框的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Vant中List組件immediate-check=false無效的解決

    Vant中List組件immediate-check=false無效的解決

    這篇文章主要介紹了Vant中List組件immediate-check=false無效的解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01

最新評論