VUE3 Composition API

1. Composition API(常用部分)

文檔:

https://vue3js.cn/docs/zh/

setup

  • 新的option, 所有的組合API函數(shù)都在此使用, 只在初始化時執(zhí)行一次
  • 函數(shù)如果返回對象, 對象中的屬性或方法, 模板中可以直接使用

ref

  • 作用: 定義一個數(shù)據(jù)的響應式
  • 語法: const xxx = ref(initValue):
    • 創(chuàng)建一個包含響應式數(shù)據(jù)的引用(reference)對象
    • js中操作數(shù)據(jù): xxx.value
    • 模板中操作數(shù)據(jù): 不需要.value
  • 一般用來定義一個基本類型的響應式數(shù)據(jù)
<template>
  <h2>{{count}}</h2>
  <hr>
  <button @click="update">更新</button>
</template>

<script>
import {
  ref
} from 'vue'
export default {

  /* 在Vue3中依然可以使用data和methods配置, 但建議使用其新語法實現(xiàn) */
  // data () {
  //   return {
  //     count: 0
  //   }
  // },
  // methods: {
  //   update () {
  //     this.count++
  //   }
  // }

  /* 使用vue3的composition API */
  setup () {

    // 定義響應式數(shù)據(jù) ref對象
    const count = ref(1)
    console.log(count)

    // 更新響應式數(shù)據(jù)的函數(shù)
    function update () {
      // alert('update')
      count.value = count.value + 1
    }

    return {
      count,
      update
    }
  }
}
</script>

3) reactive

  • 作用: 定義多個數(shù)據(jù)的響應式
  • const proxy = reactive(obj): 接收一個普通對象然后返回該普通對象的響應式代理器對象
  • 響應式轉換是“深層的”:會影響對象內部所有嵌套的屬性
  • 內部基于 ES6 的 Proxy 實現(xiàn)梢睛,通過代理對象操作源對象內部數(shù)據(jù)都是響應式的
<template>
  <h2>name: {{state.name}}</h2>
  <h2>age: {{state.age}}</h2>
  <h2>wife: {{state.wife}}</h2>
  <hr>
  <button @click="update">更新</button>
</template>

<script>
/* 
reactive: 
    作用: 定義多個數(shù)據(jù)的響應式
    const proxy = reactive(obj): 接收一個普通對象然后返回該普通對象的響應式代理器對象
    響應式轉換是“深層的”:會影響對象內部所有嵌套的屬性
    內部基于 ES6 的 Proxy 實現(xiàn)皿淋,通過代理對象操作源對象內部數(shù)據(jù)都是響應式的
*/
import {
  reactive,
} from 'vue'
export default {
  setup () {
    /* 
    定義響應式數(shù)據(jù)對象
    */
    const state = reactive({
      name: 'tom',
      age: 25,
      wife: {
        name: 'marry',
        age: 22
      },
    })
    console.log(state, state.wife)

    const update = () => {
      state.name += '--'
      state.age += 1
      state.wife.name += '++'
      state.wife.age += 2
    }

    return {
      state,
      update,
    }
  }
}
</script>

shallowRef and shallowReactive

shallowReactive : 只處理了對象內最外層屬性的響應式(也就是淺響應式)

shallowRef: 只處理了value的響應式, 不進行對象的reactive處理

什么時候用淺響應式呢?

一般情況下使用ref和reactive即可
如果有一個對象數(shù)據(jù), 結構比較深, 但變化時只是外層屬性變化 ===> shallowReactive
如果有一個對象數(shù)據(jù), 后面會產生新的對象來替換 ===> shallowRef

<template>
  <div>
    <div>
      <p>{{ counter.name }}</p>
      <button @click="handleCounter">add</button>
    </div>
    <div>
      <p>{{ user.name }}</p>
      <p>{{ user.age }}</p>
      <p>{{ user.hobby }}</p>
      <p>{{ user.child.value }}</p>
      <button @click="updateUser">update</button>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, shallowReactive, shallowRef } from 'vue';

export default defineComponent({
  setup() {
    // const counter = shallowRef(0);
    const counter = shallowRef({
      name: 'wanglizhi'
    });
    const user = shallowReactive({
      name: 'wanglizhi',
      age: 18,
      child: {
        id: 1,
        value: '11',
      },
      hobby: ['唱歌', '跳舞'],
    });

    function handleCounter() {
      counter.value.name = 'Leo';
      console.log(counter)
    }

    function updateUser() {
      // user.name = 'Leo';
      // user.age = 20;
      user.hobby[0] = '吃飯';
      user.child.value = '222';
      console.log(user)
    }

    return {
      counter,
      user,
      handleCounter,
      updateUser,
    };
  },
});
</script>

<style></style>

readonly and shallowReadonly

readonly:
深度只讀數(shù)據(jù)
獲取一個對象 (響應式或純對象) 或 ref 并返回原始代理的只讀代理溃斋。
只讀代理是深層的:訪問的任何嵌套 property 也是只讀的恤左。
shallowReadonly
淺只讀數(shù)據(jù)
創(chuàng)建一個代理缆巧,使其自身的 property 為只讀,但不執(zhí)行嵌套對象的深度只讀轉換
應用場景:
在某些特定情況下, 我們可能不希望對數(shù)據(jù)進行更新的操作, 那就可以包裝生成一個只讀代理對象來讀取數(shù)據(jù), 而不能修改或刪除

<template>
  <div>
    <div>
      <p>{{ JSON.stringify(state) }}</p>
      <button @click="update">update</button>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, readonly, shallowReadonly } from 'vue';

export default defineComponent({
  setup() {
    const state = shallowReadonly({
      name: 'wanglizhi',
      age: 18,
      child: {
        name: 'xiaowang',
        age: 10,
        child: {
          name: 'wang',
          age: 1
        }
      }
    })

    function update() {
      state.name = 'Leo';
      state.child.name = 'Leo1';
      state.child.child.name = 'Leo2';
      console.log(state)
    }
    return {
      state,
      update,
    };
  },
});
</script>

<style></style>

toRaw and markRaw

toRaw
返回由 reactive 或 readonly 方法轉換成響應式代理的普通對象狡忙。
這是一個還原方法燎竖,可用于臨時讀取,訪問不會被代理/跟蹤哥捕,寫入時也不會觸發(fā)界面更新牧抽。
markRaw
標記一個對象,使其永遠不會轉換為代理遥赚。返回對象本身
應用場景:
有些值不應被設置為響應式的扬舒,例如復雜的第三方類實例或 Vue 組件對象。
當渲染具有不可變數(shù)據(jù)源的大列表時凫佛,跳過代理轉換可以提高性能讲坎。

<template>
  <div>
    <h2>toRaw and markRow</h2>
    <div>
      <p>{{ JSON.stringify(state) }}</p>
      <button @click="update">update</button>
    </div>
    <hr>
  </div>
</template>

<script lang="ts">
import { defineComponent, toRaw, markRaw, reactive } from 'vue';

export default defineComponent({
  setup() {
    const obj = {
      name: 'wanglizhi',
      age: 18,
      child: {
        name: 'xiaowang',
        age: 10,
        child: {
          name: 'wang',
          age: 1,
        },
      },
    };
    const obj3 = markRaw(obj);
    const state = reactive(obj3);
    const obj2 = toRaw(state);

    function update() {
      state.name = 'Leo';
      state.child.name = 'Leo1';
      state.child.child.name = 'Leo2';
      console.log('obj', obj);
      console.log('state', state);
      console.log('obj2', obj2);
      console.log(obj === state)
         console.log(obj2 === obj2)
    }
    return {
      state,
      update,
    };
  },
});
</script>

<style></style>

toRef 孕惜、toRefs、 isRef and unref

toRef
為源響應式對象上的某個屬性創(chuàng)建一個 ref對象, 二者內部操作的是同一個數(shù)據(jù)值, 更新時二者是同步的
區(qū)別ref: 拷貝了一份新的數(shù)據(jù)值單獨操作, 更新時相互不影響
應用: 當要將 某個prop 的 ref 傳遞給復合函數(shù)時晨炕,toRef 很有用
toRefs
將響應式對象轉換為普通對象衫画,其中結果對象的每個 property 都是指向原始對象相應 property 的ref
isRef
判斷是否為ref
unref
如果參數(shù)為 ref瓮栗,則返回內部值削罩,否則返回參數(shù)本身。這是 val = isRef(val) ? val.value : val费奸。

<template>
  <div>
    <h2>toRef and toRefs</h2>
    <div>
      <p>{{ JSON.stringify(state) }}</p>
      <button @click="update">update</button>
    </div>
    <hr>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, toRef, toRefs, isRef, unref } from 'vue';

export default defineComponent({
  setup() {
    const obj = {
      name: 'wanglizhi',
      age: 18,
      child: {
        name: 'xiaowang',
        age: 10,
        child: {
          name: 'wang',
          age: 1,
        },
      },
    };
    const state = reactive(obj);
    const obj2 = toRef(state, 'name');
    const obj3 = toRefs(state)

    function update() {
      // state.name = 'Leo';
      // state.child.name = 'Leo1';
      // state.child.child.name = 'Leo2';
      // obj2.value = 'haha'
      obj3.name.value = 'hehe'
      console.log('obj', obj);
      console.log('state', state);
      console.log('obj2', obj2);
      console.log('obj3', obj3);
      console.log(isRef(state))
      // console.log(isRef(obj2))
      // console.log(isRef(obj3))
      // console.log(isRef(obj3.name))
      // console.log(unref(state))
      // console.log(unref(obj2))
    }
    return {
      state,
      update,
    };
  },
});
</script>

<style></style>

customRef

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末弥激,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子愿阐,更是在濱河造成了極大的恐慌微服,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缨历,死亡現(xiàn)場離奇詭異职辨,居然都是意外死亡,警方通過查閱死者的電腦和手機戈二,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喳资,“玉大人觉吭,你說我怎么就攤上這事∑偷耍” “怎么了鲜滩?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長节值。 經(jīng)常有香客問我徙硅,道長,這世上最難降的妖魔是什么搞疗? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任嗓蘑,我火速辦了婚禮,結果婚禮上匿乃,老公的妹妹穿的比我還像新娘桩皿。我一直安慰自己,他們只是感情好幢炸,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布泄隔。 她就那樣靜靜地躺著,像睡著了一般宛徊。 火紅的嫁衣襯著肌膚如雪佛嬉。 梳的紋絲不亂的頭發(fā)上逻澳,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機與錄音暖呕,去河邊找鬼斜做。 笑死,一個胖子當著我的面吹牛缰揪,可吹牛的內容都是我干的陨享。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼钝腺,長吁一口氣:“原來是場噩夢啊……” “哼抛姑!你這毒婦竟也來了?” 一聲冷哼從身側響起艳狐,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤定硝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后毫目,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔬啡,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年镀虐,在試婚紗的時候發(fā)現(xiàn)自己被綠了箱蟆。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡刮便,死狀恐怖空猜,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情恨旱,我是刑警寧澤辈毯,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站搜贤,受9級特大地震影響谆沃,放射性物質發(fā)生泄漏。R本人自食惡果不足惜仪芒,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一唁影、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧掂名,春花似錦夭咬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至膀钠,卻和暖如春掏湾,著一層夾襖步出監(jiān)牢的瞬間裹虫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工融击, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留筑公,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓尊浪,卻偏偏與公主長得像匣屡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拇涤,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內容