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

詳解vue2和vue3如何定義響應(yīng)式數(shù)據(jù)

 更新時(shí)間:2023年11月09日 14:33:59   作者:ashklwi  
這篇文章主要是來(lái)和大家一起討論一下vue2和vue3是如何定義響應(yīng)式數(shù)據(jù)的,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解下

響應(yīng)式原理

Vue2和Vue3的響應(yīng)式實(shí)現(xiàn)原理是不同的

  • Vue2底層是通過(guò)es5Object.defineProperty,使用Object.defineProperty()進(jìn)行數(shù)據(jù)劫持,結(jié)合訂閱發(fā)布的方式實(shí)現(xiàn),有一定的局限性。
  • Vue3底層是通過(guò)es6Porxy, 通過(guò)Proxy代理,使用ref或者reactive將數(shù)據(jù)轉(zhuǎn)化為響應(yīng)式數(shù)據(jù),能夠更好地支持動(dòng)態(tài)添加屬性和刪除屬性。它解決了Vue2底層實(shí)現(xiàn)的缺點(diǎn),對(duì)數(shù)組、層級(jí)比較深的對(duì)象處理都很優(yōu)秀,但缺點(diǎn)是瀏覽器兼容不是很好。

Vue2的響應(yīng)式數(shù)據(jù)

在Vue2中,是使用選項(xiàng)式API的方式來(lái)編寫(xiě)代碼,比如data()、computed()、watch等方法實(shí)現(xiàn)響應(yīng)式

Vue3的響應(yīng)式數(shù)據(jù)

reactive和ref

reactive

reactive定義引用數(shù)據(jù)類(lèi)型(以對(duì)象和數(shù)組舉例),它能夠?qū)?fù)雜數(shù)據(jù)類(lèi)型的內(nèi)部屬性或者數(shù)據(jù)項(xiàng)聲明為響應(yīng)式數(shù)據(jù),所以reactive的響應(yīng)式是深層次的,其底層是通過(guò)ES6的Proxy來(lái)實(shí)現(xiàn)數(shù)據(jù)響應(yīng)式,相對(duì)于Vue2的Object.defineProperty,具有能監(jiān)聽(tīng)增刪操作,能監(jiān)聽(tīng)對(duì)象屬性的變化等優(yōu)點(diǎn)

  • reactive是一個(gè)函數(shù),它可以定義一個(gè)復(fù)雜數(shù)據(jù)類(lèi)型,成為響應(yīng)式數(shù)據(jù);
  • 通常用來(lái)定義響應(yīng)式的對(duì)象數(shù)據(jù)。
<template>
  <div>name:{{obj.name}}</div>
  <button @click="updateName">修改name</button>
</template>
<script>
import { reactive } from 'vue'
export default {
    setup() {
        // 定義響應(yīng)式對(duì)象
        const obj = reactive({
            name: 'lisi',
            age:20
        })
        const updateName = () => {
            obj.name = '我是修改后的name'
            console.log('我是按鈕..........');
        };
        return {
            obj,
            updateName
        }
    }
}
</script>

ref函數(shù)

ref函數(shù),常用于簡(jiǎn)單數(shù)據(jù)類(lèi)型定義為響應(yīng)式數(shù)據(jù),其實(shí)也可以定義復(fù)雜數(shù)據(jù)類(lèi)型的響應(yīng)式數(shù)據(jù),對(duì)于數(shù)據(jù)未知的情況下ref是最適用的。

在修改值,獲取值的時(shí)候,需要.value。在模板中使用ref申明的響應(yīng)式數(shù)據(jù),可以省略.value,在js代碼中修改ref聲明的數(shù)據(jù),需要加上.value。

<template>
  <div>name:{{name}}</div>
  <button @click="changeName">修改name</button>
</template>

<script>
import { ref } from 'vue'
export default {
    setup() {
        const name = ref('zhangsan');
        const changeName = () => {
            name.value = 'lisi'
        }
        return {
            name,
            changeName
        }
    }
} 
</script>

兩者的不同

  • ref用于定義基本類(lèi)型和引用類(lèi)型,reactive僅用于定義引用類(lèi)型
  • reactive只能用于定義引用數(shù)據(jù)類(lèi)型的原因在于內(nèi)部是通過(guò)ES6的Proxy實(shí)現(xiàn)響應(yīng)式的,而Proxy不適用于基本數(shù)據(jù)類(lèi)型
  • ref定義對(duì)象時(shí),底層會(huì)通過(guò)reactive轉(zhuǎn)換成具有深層次的響應(yīng)式對(duì)象,所以ref本質(zhì)上是reactive的再封裝(會(huì)判斷數(shù)據(jù)的類(lèi)型進(jìn)行不同處理)
  • 在腳本里使用ref定義的數(shù)據(jù)時(shí),記得加.value后綴
  • 在定義數(shù)組時(shí),建議使用ref,從而可避免reactive定義時(shí)值修改導(dǎo)致的響應(yīng)式丟失問(wèn)題
const tableData = reactive([]) // 定義
const getTableData = async () => {
	const { data } = await getTableDataApi() // 模擬接口獲取表格數(shù)據(jù)
	tableData = data // 修改,錯(cuò)誤示例,這樣賦值會(huì)使tableData失去響應(yīng)式
}

// 方法一:改為 ref 定義
const tableData = ref([])
const getTableData = async () => {
	const { data } = await getTableDataApi()
	tableData.value = data // 使用.value重新賦值
}
// 方法二:使用 push 方法
const tableData = reactive([])
const getTableData = async () => {
	const { data } = await getTableDataApi()
	tableData.push(...data) // 先使用...將data解構(gòu),再使用push方法
}
// 方法三:定義時(shí)數(shù)組外層嵌套一個(gè)對(duì)象
const tableData = reactive({ list:[] })
const getTableData = async () => {
	const { data } = await getTableDataApi()
	tableData.list = data // 通過(guò)訪問(wèn)list屬性重新賦值
}
// 方法四:賦值前再包一層 reactive
const tableData = reactive([])
const getTableData = async () => {
	const { data } = await getTableDataApi()
	tableData = reactive(data) // 賦值前再包一層reactive
}

為什么需要兩個(gè)

雖然ref函數(shù)既可以處理基本數(shù)據(jù)類(lèi)型也可以處理引用數(shù)據(jù)類(lèi)型,但是在普通js代碼里修改該響應(yīng)式數(shù)據(jù)的值時(shí)需要使用.value的寫(xiě)法,會(huì)存在.value的嵌套問(wèn)題,因此使用reactive來(lái)處理引用數(shù)據(jù)類(lèi)型,避免該問(wèn)題。

toRef和toRefs

ref是對(duì)元數(shù)據(jù)的拷貝,修改響應(yīng)式數(shù)據(jù)時(shí)不會(huì)影響之前的數(shù)據(jù),視圖會(huì)更新。tooRef和toRefs是對(duì)元數(shù)據(jù)的引用,修改響應(yīng)式數(shù)據(jù)時(shí),原數(shù)據(jù)也會(huì)改變,但是視圖不會(huì)更新,只有原始數(shù)據(jù)改變后,該數(shù)據(jù)和視圖都會(huì)更新。toRef修改的是對(duì)象的某個(gè)屬性,toRefs修改的是整個(gè)對(duì)象

toRef

toRef 函數(shù)的作用:轉(zhuǎn)換響應(yīng)式對(duì)象中某個(gè)屬性為單獨(dú)響應(yīng)式數(shù)據(jù),并且轉(zhuǎn)換后的值和之前是關(guān)聯(lián)的(ref 函數(shù)也可以轉(zhuǎn)換,但值非關(guān)聯(lián))。

<template>
  <div class="container">
      <h2>name: {{ obj.name }} age: {{obj.age}}</h2>
      <button @click="updateName">修改數(shù)據(jù)</button>
  </div></template><script>
  import { reactive } from 'vue'
  export default {
      name: 'App',
      setup() {
          const obj = reactive({
              name: '初映',
              age: 18,
              address: '江西',
              sex: '男',
          })
          const updateName = () => {
              obj.name = '初映CY的前說(shuō)'
          }
          return { obj, updateName }
      },
  }</script>

這樣寫(xiě)有幾個(gè)問(wèn)題:

  • 模板中都要使用 obj. 進(jìn)行獲取數(shù)據(jù),較為麻煩
  • 明明模板中只用到了 name 和 age,卻把整個(gè) obj 進(jìn)行了導(dǎo)出,沒(méi)必要,性能浪費(fèi)。

使用toRef進(jìn)行修改,只需要將需要的屬性return出去即好,且模板中也不需要加obj.前綴了。

<template>
  <div class="container">
      <h2>name: {{ name }} </h2>
      <button @click="updateName">修改數(shù)據(jù)</button>
  </div></template><script>
  import { reactive,toRef  } from 'vue'
  export default {
      name: 'App',
      setup() {
          const obj = reactive({
              name: '初映',
              age: 18,
              address: '江西',
              sex: '男',
          })
          const name = toRef(obj, 'name')
          const updateName = () => {
              obj.name = '初映CY的前說(shuō)'
          }
          return { name, updateName }
      },
  }</script>

toRefs

toRefs 函數(shù)的作用:轉(zhuǎn)換響應(yīng)式對(duì)象中所有屬性為單獨(dú)響應(yīng)式數(shù)據(jù),并且轉(zhuǎn)換后的值和之前是關(guān)聯(lián)的。

<template>
<div>{{name}}</div>
<div>{{age}}</div>
<button @click="update">修改name</button>
</template>

<script>
import {reactive, toRefs} from 'vue'

export default {
    setup() {
        const obj = reactive({
            name: '張三',
            age:18
        })
        console.log(obj);

        const obj2 = toRefs(obj);
        console.log(obj2); //發(fā)現(xiàn)obj2里面的name和age都是響應(yīng)式屬性,指向obj的屬性

        // 解構(gòu)之后重新賦值的是普通對(duì)象
        const obj3 = { ...obj };
        console.log(obj3);

        const update =()=> {
            obj.name = '我是修改的原始數(shù)據(jù)的obj'
        }
        return {
            // 解構(gòu)obj2,用的時(shí)候直接拿屬性名,不需要obj2.name或obj2.age
            ...obj2,
            update
        }
    }
}
</script>

修改原始數(shù)據(jù)obj后會(huì)發(fā)現(xiàn),轉(zhuǎn)換過(guò)后的obj2中的值會(huì)跟著改變。

以上就是詳解vue2和vue3如何定義響應(yīng)式數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于vue定義響應(yīng)式數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue 使用moment獲取當(dāng)前時(shí)間及一月前的時(shí)間

    vue 使用moment獲取當(dāng)前時(shí)間及一月前的時(shí)間

    開(kāi)發(fā)中會(huì)有要獲取當(dāng)前日期的需求,有的是獲取到當(dāng)前月份,本文就介紹了vue獲取當(dāng)前日期時(shí)間(moment、new?Date()),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2023-08-08
  • vue動(dòng)畫(huà)—通過(guò)鉤子函數(shù)實(shí)現(xiàn)半場(chǎng)動(dòng)畫(huà)操作

    vue動(dòng)畫(huà)—通過(guò)鉤子函數(shù)實(shí)現(xiàn)半場(chǎng)動(dòng)畫(huà)操作

    這篇文章主要介紹了vue動(dòng)畫(huà)—通過(guò)鉤子函數(shù)實(shí)現(xiàn)半場(chǎng)動(dòng)畫(huà)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • Vue3中watch的用法與最佳實(shí)踐指南

    Vue3中watch的用法與最佳實(shí)踐指南

    這篇文章主要給大家介紹了關(guān)于Vue3中watch用法與最佳實(shí)踐的相關(guān)資料,watch的作用可以監(jiān)控一個(gè)值的變換,并調(diào)用因?yàn)樽兓枰獔?zhí)行的方法,可以通過(guò)watch動(dòng)態(tài)改變關(guān)聯(lián)的狀態(tài),需要的朋友可以參考下
    2021-07-07
  • 一文詳解Vue中加上key后發(fā)生什么

    一文詳解Vue中加上key后發(fā)生什么

    本文主要介紹了一文詳解Vue中加上key后發(fā)生什么,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • VUE使用ElementUI下拉框 @change事件數(shù)據(jù)不回顯問(wèn)題

    VUE使用ElementUI下拉框 @change事件數(shù)據(jù)不回顯問(wèn)題

    這篇文章主要介紹了VUE使用ElementUI下拉框 @change事件數(shù)據(jù)不回顯問(wèn)題。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • DataV?全屏容器組件源碼解析

    DataV?全屏容器組件源碼解析

    這篇文章主要為大家介紹了DataV?全屏容器組件源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Vue出現(xiàn)did you register the component correctly?解決方案

    Vue出現(xiàn)did you register the component 

    這篇文章主要介紹了Vue出現(xiàn)did you register the component correctly?解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Vue中watch監(jiān)聽(tīng)屬性新舊值相同的問(wèn)題解決方案

    Vue中watch監(jiān)聽(tīng)屬性新舊值相同的問(wèn)題解決方案

    這篇文章主要給大家分享了Vue中watch監(jiān)聽(tīng)屬性新舊值相同問(wèn)題解決方案,如果有遇到相同問(wèn)題的朋友,可以參考閱讀本文
    2023-08-08
  • 解決Vue?input輸入框卡死的問(wèn)題

    解決Vue?input輸入框卡死的問(wèn)題

    這篇文章主要介紹了解決Vue?input輸入框卡死的問(wèn)題,文中同時(shí)給大家提到了Vue-element中el-input輸入卡頓問(wèn)題及解決方法,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • 基于Vuejs和Element的注冊(cè)插件的編寫(xiě)方法

    基于Vuejs和Element的注冊(cè)插件的編寫(xiě)方法

    這篇文章主要介紹了基于Vuejs和Element的注冊(cè)插件的編寫(xiě)方法,需要的朋友可以參考下
    2017-07-07

最新評(píng)論

黑山县| 大宁县| 璧山县| 凤冈县| 青浦区| 苏州市| 泾川县| 临汾市| 健康| 苍山县| 姚安县| 新宾| 安乡县| 商水县| 垣曲县| 河间市| 香格里拉县| 延吉市| 寿阳县| 巴彦县| 崇信县| 扎兰屯市| 汕头市| 台北县| 北川| 汶上县| 电白县| 邯郸县| 内丘县| 满城县| 象山县| 隆安县| 华容县| 石渠县| 仙游县| 长海县| 延寿县| 霍城县| 科技| 潜江市| 马山县|