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

詳解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)文章

  • 詳解vue2路由vue-router配置(懶加載)

    詳解vue2路由vue-router配置(懶加載)

    本篇文章主要介紹了詳解vue2路由vue-router配置(懶加載),實(shí)例分析了vue-router懶加載的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-04-04
  • Vue?element樹(shù)形控件添加虛線(xiàn)詳解

    Vue?element樹(shù)形控件添加虛線(xiàn)詳解

    這篇文章主要為大家介紹了Vue?element樹(shù)形控件添加虛線(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助<BR>
    2021-11-11
  • 解決vue2.0 element-ui中el-upload的before-upload方法返回false時(shí)submit()不生效問(wèn)題

    解決vue2.0 element-ui中el-upload的before-upload方法返回false時(shí)submit(

    這篇文章主要介紹了vue2.0 element-ui中el-upload的before-upload方法返回false時(shí)submit()不生效的解決方法,這里需要主要項(xiàng)目中用的element-ui是V1.4.3,感興趣的朋友參考下吧
    2018-08-08
  • vue在外部方法給下拉框賦值后不顯示label的解決

    vue在外部方法給下拉框賦值后不顯示label的解決

    這篇文章主要介紹了vue在外部方法給下拉框賦值后不顯示label的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • vue2中filter()的實(shí)現(xiàn)代碼

    vue2中filter()的實(shí)現(xiàn)代碼

    vue2.0里,不再有自帶的過(guò)濾器,需要自己定義過(guò)濾器。下面通過(guò)實(shí)例代碼給大家介紹vue2中filter()的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2017-07-07
  • 解讀Vue組件注冊(cè)方式

    解讀Vue組件注冊(cè)方式

    無(wú)論是Vue還是React,都有組件的概念。組件,就是能和別人組合在一起的物件。在前端頁(yè)面開(kāi)發(fā)過(guò)程中,將一個(gè)頁(yè)面劃分成一個(gè)個(gè)小的模塊,每個(gè)模塊單獨(dú)定義,每個(gè)模塊就是一個(gè)組件。組件可以進(jìn)行復(fù)用,A頁(yè)面和B頁(yè)面有一個(gè)相似的模塊,可以抽離成一個(gè)可局部修改的組件。
    2021-05-05
  • 前端MVVM框架解析之雙向綁定

    前端MVVM框架解析之雙向綁定

    這篇文章主要介紹了MVVM 框架解析之雙向綁定,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • vue2和vue3子組件父組件之間的傳值方法

    vue2和vue3子組件父組件之間的傳值方法

    在組件化開(kāi)發(fā)的過(guò)程中難免會(huì)遇見(jiàn)子組件和父組件之間的通訊那么這里講關(guān)于vue2和vue3不同的通訊方式,文中有詳細(xì)的代碼示例供大家參考,感興趣的同學(xué)可以閱讀下
    2023-05-05
  • Vue?element-ui?el-cascader?只能末級(jí)多選問(wèn)題

    Vue?element-ui?el-cascader?只能末級(jí)多選問(wèn)題

    這篇文章主要介紹了Vue?element-ui?el-cascader?只能末級(jí)多選問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue3中使用百度地圖的簡(jiǎn)單步驟

    vue3中使用百度地圖的簡(jiǎn)單步驟

    最近項(xiàng)目要用到百度地圖api,好久沒(méi)用到地圖,就百度了一番,下面這篇文章主要給大家介紹了關(guān)于vue3中使用百度地圖的簡(jiǎn)單步驟,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06

最新評(píng)論