最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue3聲明響應(yīng)式狀態(tài)使用(含ref,reactive,toRef(),toRefs()等)

 更新時(shí)間:2024年07月18日 10:42:08   作者:朝陽(yáng)39  
這篇文章主要介紹了vue3聲明響應(yīng)式狀態(tài)使用(含ref,reactive,toRef(),toRefs()等),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Vue 3 中的數(shù)據(jù)基于 JavaScript Proxy (代理) 實(shí)現(xiàn)響應(yīng)式

( vue2 中的數(shù)據(jù)通過(guò) Object.defineProperty() 方法和對(duì)數(shù)組變異方法的重寫(xiě),實(shí)現(xiàn)響應(yīng)式)

選項(xiàng)式 API

用 data 選項(xiàng)聲明響應(yīng)式狀態(tài),值為返回一個(gè)對(duì)象的函數(shù)。

  • 在創(chuàng)建組件實(shí)例的時(shí)候會(huì)調(diào)用此函數(shù)
  • 函數(shù)返回的對(duì)象會(huì)用響應(yīng)式系統(tǒng)進(jìn)行包裝
  data() {
    return {
      count: 1
    }
  },

注意事項(xiàng)

  • data 的頂層屬性避免用 $_開(kāi)頭(Vue 在組件實(shí)例上暴露的內(nèi)置 API 使用 $ 作為前綴,也為內(nèi)部屬性保留 _ 前綴。)
  • 未在data中定義的組件實(shí)例新屬性,無(wú)法觸發(fā)響應(yīng)式更新。
  • 始終通過(guò) this 來(lái)訪問(wèn)響應(yīng)式狀態(tài)
  data() {
    return {
      someObject: {}
    }
  },
  mounted() {
    const newObject = {}
    this.someObject = newObject

    console.log(newObject === this.someObject) // false
  }

這里原始的 newObject 不會(huì)變?yōu)轫憫?yīng)式。

組合式 API

方式一 ref 【推薦】

所有類型的數(shù)據(jù),都推薦使用 ref 聲明響應(yīng)式。

import { ref } from 'vue'

// 定義一個(gè)初始值為數(shù)字 0 的響應(yīng)式變量 countRef  
const countRef = ref(0)

// 得到一個(gè)帶有 .value 屬性的 ref 對(duì)象
console.log(countRef ) // { value: 0 }

// 通過(guò) .value 訪問(wèn) ref 響應(yīng)式變量的值
console.log(countRef.value) // 0

// 通過(guò) .value 修改 ref 響應(yīng)式變量的值
countRef.value++
  • 參數(shù)為響應(yīng)式變量的初始值(當(dāng)參數(shù)是一個(gè)對(duì)象時(shí),ref() 會(huì)在內(nèi)部調(diào)用reactive()
  • 返回一個(gè)帶有 .value 屬性的 ref 對(duì)象
  • 建議變量名以Ref為后綴,以便識(shí)別其是一個(gè) ref 對(duì)象
  • 模板中使用時(shí),ref 對(duì)象會(huì)自動(dòng)解包,無(wú)需使用.value
<button @click="countRef++">
  {{ countRef }}
</button>
  • ref 對(duì)象在作為響應(yīng)式對(duì)象的屬性被訪問(wèn)或修改時(shí)會(huì)自動(dòng)解包。
const countRef = ref(0)

// reactive 的用法詳見(jiàn)下文
const state = reactive({
  count:countRef 
})

console.log(state.count) // 0 ,無(wú)需寫(xiě)成 state.count.value

state.count = 1 // 無(wú)需寫(xiě)成 state.count.value
console.log(countRef .value) // 1
  • ref 的另一個(gè)功能是獲取模板引用(即 vue2 中的 this.$refs)
<script setup>
import { ref, onMounted } from 'vue'

// 獲取到 ref 屬性為 input 的模板元素的引用(ref 變量名必須和模板里的 ref 屬性值相同)
const input = ref(null)

// 生命周期:DOM 掛載完成
onMounted(() => {
  // input 輸入框獲得焦點(diǎn)(注意此處需使用.value)
  input.value.focus()
})
</script>

<template>
  <!-- ref 屬性為 input 的模板元素 -->
  <input ref="input" />
</template>
  • 為什么需要 ref

因?yàn)?vue3 的響應(yīng)式是通過(guò) proxy 實(shí)現(xiàn)的,但 proxy 只能給對(duì)象添加響應(yīng)式,無(wú)法給值類型的數(shù)據(jù)添加響應(yīng)式,所以需要通過(guò) ref() 函數(shù)先將值類型的數(shù)據(jù)包裝成一個(gè)帶 value 屬性的 ref 對(duì)象,才能實(shí)現(xiàn)值類型數(shù)據(jù)的響應(yīng)式。

  • 為什么需要 .value

因?yàn)?ref() 函數(shù)返回的是一個(gè) ref 對(duì)象,響應(yīng)式變量的值存儲(chǔ)在 ref 對(duì)象的value 屬性中,所以在 js 中讀取和修改響應(yīng)式變量的值的時(shí)候,都需要 .value ,但在以下情況中,為了方便使用,vue 對(duì) ref 對(duì)象進(jìn)行了自動(dòng)解包,所以無(wú)需 .value

  • 模板中使用 ref 對(duì)象
  • ref 對(duì)象作為響應(yīng)式對(duì)象的屬性被訪問(wèn)或修改

TS 中給 ref 聲明類型

  • ref 會(huì)根據(jù)初始化時(shí)的值推導(dǎo)其類型
// 推導(dǎo)出的類型:Ref<number>
const year = ref(2020)
  • 但比較復(fù)雜的數(shù)據(jù)類型,需用 Ref
import { ref } from 'vue'
import type { Ref } from 'vue'

interface userInfo {
  id: number
  name: String
}

const userList: Ref<userInfo[]> = ref([])

方式二 reactive

用于創(chuàng)建對(duì)象類型數(shù)據(jù)的響應(yīng)式。

import { reactive } from 'vue'
const state = reactive({ count: 0 })
<button @click="state.count++">
  {{ state.count }}
</button>
  • reactive() 無(wú)需對(duì)源數(shù)據(jù)添加類似 ref 的包裝,可使對(duì)象本身具有響應(yīng)性
  • reactive() 返回的是一個(gè)原始對(duì)象的 Proxy,它和原始對(duì)象是不相等的
const raw = {}
const proxy = reactive(raw)

// 代理對(duì)象和原始對(duì)象不是全等的
console.log(proxy === raw) // false

reactive() 的局限性

  • 只能用于對(duì)象類型數(shù)據(jù) (對(duì)象、數(shù)組和如 Map、Set 這樣的集合類型),不能用于 string、number 或 boolean 這樣的值類型數(shù)據(jù)
  • 替換整個(gè)對(duì)象會(huì)丟失響應(yīng)式(Vue 的響應(yīng)式跟蹤是通過(guò)屬性訪問(wèn)實(shí)現(xiàn)的),所以只能通過(guò)修改屬性來(lái)修改 reactive() 創(chuàng)建的響應(yīng)式變量。
  • 解構(gòu)會(huì)丟失響應(yīng)式
const state = reactive({ count: 0 })

// 當(dāng)解構(gòu)時(shí),count 已經(jīng)與 state.count 斷開(kāi)連接
let { count } = state
// 不會(huì)影響原始的 state
count++

其他相關(guān) API

vue 提供了專門(mén)的API 來(lái)實(shí)現(xiàn)在不丟失響應(yīng)式的情況下,解構(gòu)響應(yīng)式對(duì)象(reactive 創(chuàng)建),它們不創(chuàng)造響應(yīng)式 (如 ref , reactive),而是延續(xù)響應(yīng)式 (toRef , toRefs) !

  • toRef()

基于響應(yīng)式對(duì)象上的屬性,創(chuàng)建 ref (與源屬性保持同步)

  • 第一個(gè)參數(shù)為 響應(yīng)式對(duì)象(reactive 創(chuàng)建)
  • 第二個(gè)參數(shù)為 屬性名
const state = reactive({
  foo: 1
})

// 基于響應(yīng)式對(duì)象 state 上的屬性 foo ,創(chuàng)建 ref
const fooRef = toRef(state, 'foo')

// 更改該 ref 會(huì)更新源屬性
fooRef.value++
console.log(state.foo) // 2

// 更改源屬性也會(huì)更新該 ref
state.foo++
console.log(fooRef.value) // 3

vue3.3+ 新增了將值、refs 或 getters 規(guī)范化為 refs 的功能,詳見(jiàn)官網(wǎng)

https://cn.vuejs.org/api/reactivity-utilities.html#toref

  • toRefs()

將響應(yīng)式對(duì)象轉(zhuǎn)換為每個(gè)屬性都指向源對(duì)象相應(yīng)屬性的 ref 的普通對(duì)象

  • 推薦用法:合成函數(shù)返回響應(yīng)式對(duì)象時(shí),使用 toRefs,以便解構(gòu)賦值時(shí)不丟失響應(yīng)式。(詳見(jiàn)下文的范例)
const state = reactive({
  foo: 1,
  bar: 2
})

// 得到一個(gè)每個(gè)屬性都是 ref 的普通對(duì)象
const stateAsRefs = toRefs(state)
/*
stateAsRefs 的類型:{
  foo: Ref<number>,
  bar: Ref<number>
}
*/

// 源屬性改變,Refs 對(duì)象里的 ref 屬性會(huì)同步改變
state.foo++
console.log(stateAsRefs.foo.value) // 2

// Refs 對(duì)象里的 ref 屬性改變,源屬性會(huì)同步改變
stateAsRefs.foo.value++
console.log(state.foo) // 3

應(yīng)用范例:解構(gòu)對(duì)象屬性,簡(jiǎn)化模板引用

<!-- 組合式API -->
<script setup>
import { reactive, toRefs } from "vue";

function getMyInfo() {
  const me = reactive({
    name: "朝陽(yáng)",
    age: 35,
  });

  // 使用 toRefs 避免丟失響應(yīng)式
  return toRefs(me);
}

// 通過(guò)解構(gòu)賦值,便于模板中使用
let { name, age } = getMyInfo();

const changeName = () => {
  name.value = "張三";
};
</script>

<template>
  <p>姓名:{{ name }}</p>
  <p>年齡:{{ age }}</p>
  <button @click="changeName">改名</button>
</template>
  • isRef()

判斷是否為 ref

let age = ref(35)
if (isRef(age)) {
}
  • isReactive()

判斷一個(gè)對(duì)象是否是由 reactive() 或 shallowReactive() 創(chuàng)建的代理。

  • isProxy()

判斷一個(gè)對(duì)象是否是由 reactive()、readonly()、shallowReactive() 或 shallowReadonly() 創(chuàng)建的代理。

  • unref()

對(duì) ref 對(duì)象解包,是 isRef(val) ? val.value : val 的語(yǔ)法糖

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue異步請(qǐng)求導(dǎo)致頁(yè)面數(shù)據(jù)渲染錯(cuò)誤問(wèn)題解決方法示例

    Vue異步請(qǐng)求導(dǎo)致頁(yè)面數(shù)據(jù)渲染錯(cuò)誤問(wèn)題解決方法示例

    這篇文章主要為大家介紹了Vue中異步請(qǐng)求導(dǎo)致頁(yè)面數(shù)據(jù)渲染錯(cuò)誤問(wèn)題解決方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件

    vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件

    這篇文章主要介紹了vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件,幫助大家更好的理解和學(xué)習(xí)使用vue框架,感興趣的朋友可以了解下
    2021-02-02
  • Vue3.0監(jiān)聽(tīng)器watch與watchEffect詳解

    Vue3.0監(jiān)聽(tīng)器watch與watchEffect詳解

    在 Vue 3 中,watch 仍然是一種用于監(jiān)聽(tīng)數(shù)據(jù)變化并執(zhí)行相應(yīng)操作的方式,不過(guò)在組合式 API 中,watch 的使用方式與選項(xiàng)式 API 略有不同,這篇文章主要介紹了Vue3.0監(jiān)聽(tīng)器watch與watchEffect,需要的朋友可以參考下
    2023-12-12
  • vue組件name的作用小結(jié)

    vue組件name的作用小結(jié)

    大家在寫(xiě)vue項(xiàng)目的時(shí)候會(huì)遇到給組件的各種命名,接下來(lái)通過(guò)本文給大家分享vue組件name的作用小結(jié),感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-05-05
  • 基于Vue3實(shí)現(xiàn)無(wú)限滾動(dòng)組件的示例代碼

    基于Vue3實(shí)現(xiàn)無(wú)限滾動(dòng)組件的示例代碼

    如果你在社交媒體上停留的時(shí)間過(guò)長(zhǎng),那么,你所在的網(wǎng)站很可能正在使用無(wú)限滾動(dòng)組件。這篇文章教你利用Vue3實(shí)現(xiàn)無(wú)限滾動(dòng)組件,感興趣的可以參考一下
    2022-09-09
  • Vue中一個(gè)組件調(diào)用其他組件的方法詳解(非父子組件)

    Vue中一個(gè)組件調(diào)用其他組件的方法詳解(非父子組件)

    vue中最常見(jiàn)子父組件產(chǎn)值,大家一定都很熟悉,最近項(xiàng)目中碰到非父組件中調(diào)用子組件方法的問(wèn)題,這篇文章主要給大家介紹了關(guān)于Vue中一個(gè)組件調(diào)用其他組件的方法(非父子組件),需要的朋友可以參考下
    2022-10-10
  • vue項(xiàng)目使用element?ui詳解

    vue項(xiàng)目使用element?ui詳解

    文章介紹了如何在Vue項(xiàng)目中使用Element?Plus?UI框架,包括創(chuàng)建項(xiàng)目、安裝Element?Plus、在項(xiàng)目中引入和使用Element組件以及如何修改樣式屬性
    2025-12-12
  • vue3 Vite 進(jìn)階rollup命令行使用詳解

    vue3 Vite 進(jìn)階rollup命令行使用詳解

    這篇文章主要介紹了vue3 Vite 進(jìn)階rollup命令行使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • vue3實(shí)現(xiàn)圖片瀑布流展示效果實(shí)例代碼

    vue3實(shí)現(xiàn)圖片瀑布流展示效果實(shí)例代碼

    這篇文章主要介紹了vue3實(shí)現(xiàn)圖片瀑布流展示效果的相關(guān)資料,該組件可以調(diào)整列數(shù)、支持懶加載、自定義每頁(yè)滾動(dòng)數(shù)量、高度和點(diǎn)擊效果,作者展示了組件的效果,并詳細(xì)說(shuō)明了實(shí)現(xiàn)方法,包括組件的創(chuàng)建和依賴的工具庫(kù),需要的朋友可以參考下
    2024-11-11
  • 使用vuex的state狀態(tài)對(duì)象的5種方式

    使用vuex的state狀態(tài)對(duì)象的5種方式

    本文給大家介紹了使用vuex的state狀態(tài)對(duì)象的5種方式,給大家貼出了我的vuex的結(jié)構(gòu),感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-04-04

最新評(píng)論

北票市| 墨玉县| 赞皇县| 江西省| 卓资县| 林西县| 垦利县| 新源县| 延津县| 大姚县| 宝清县| 陆河县| 广河县| 高淳县| 海门市| 明水县| 安乡县| 恩平市| 通海县| 浦县| 齐河县| 中山市| 新宾| 特克斯县| 荔浦县| 全椒县| 高州市| 岱山县| 永昌县| 永平县| 江城| 揭西县| 枞阳县| 衡水市| 环江| 中山市| 卢龙县| 永福县| 伊金霍洛旗| 建瓯市| 芒康县|