Vue3——Hook函數(shù) & 生命周期 & toRef和toRefs & 其他的組合式API

一、Hook函數(shù)

Vue3 的hook函數(shù)相當(dāng)于 vue2 的 mixin鸳址,不同點(diǎn)在于hooks是函數(shù)瘩蚪。Vue3的hook函數(shù)可以幫助我們提高代碼的復(fù)用性,能在不同的組件中都使用hook函數(shù)稿黍。

在src目錄下建立一個(gè) hooks 文件夾疹瘦,文件夾中新建一個(gè)我們要用的方法的名字.js文件(一般情況下use開頭)。
useCar.js

import { ref, computed } from 'vue'
export default function () {
    let carName = ref("奔馳")
    let carPrice = ref(50000)
    // 修改汽車名稱
    let updateCarName = (name) => {
        carName.value = name
    }
    // 修改汽車價(jià)格
    let updateCarPrice = (price) => {
        carPrice.value = price
    }
    let usaCarPrice = computed(() => {
        return '$' + (carPrice.value / (Math.random() + 6)).toFixed(2)
    })
    return {
        carName,
        carPrice,
        updateCarName,
        updateCarPrice,
        usaCarPrice
    }
}

usePlane.js

// 導(dǎo)入ref,computed
import { ref, computed } from "vue";
export default function () {
  // 飛機(jī)名稱
  let planeName = ref("波音747");
  // 飛機(jī)價(jià)格
  let planePrice = ref(20000);
  // 修改飛機(jī)名稱的方法
  let updatePlaneName = (name) => {
    planeName.value = name;
  };
  // 修改飛機(jī)價(jià)格的方法
  let updatePlanePrice = (price) => {
    planePrice.value = price;
  };
  // 飛機(jī)在美國的價(jià)格
  let usaPlanePrice = computed(() => {
    return "$" + (planePrice.value / (Math.random() + 6)).toFixed(2);
  });
  return {
    planeName,
    planePrice,
    updatePlaneName,
    updatePlanePrice,
    usaPlanePrice,
  };
}

組件
將文件引入到要使用的組件中巡球。

<div class="child">
    <div class="car">
        <p>汽車名稱:{{carName}}<button @click="updateCarName('寶馬')">修改汽車名稱</button></p>
        <p>汽車價(jià)格:{{'¥'+carPrice}}<button @click="updateCarPrice(10000)">修改汽車價(jià)格</button></p>
        <p>美國價(jià)格:{{usaCarPrice}}</p>
    </div>
    <hr>
    <div class="plane">
        <p>汽車名稱:{{planeName}}<button @click="updatePlaneName('B2轟炸機(jī)')">修改飛機(jī)名稱</button></p>
        <p>汽車價(jià)格:{{'¥'+planePrice}}<button @click="updatePlanePrice(50000)">修改飛機(jī)價(jià)格</button></p>
        <p>美國價(jià)格:{{usaPlanePrice}}</p>
    </div>
</div>
import {computed, ref} from 'vue'
// 導(dǎo)入hook函數(shù)useCar
import useCar from '../hooks/useCar'
// 導(dǎo)入hook函數(shù)usePlane
import usePlane from '../hooks/usePlane'
export default {
  name: "Child",
  setup() {
      return {
          ...useCar(),
          ...usePlane()
      }
  }
};

二言沐、生命周期

1、Vue3 中酣栈,可以在 setup() 函數(shù)中使用生命周期险胰,定義組合式API生命周期函數(shù)。組合式API生命周期函數(shù)矿筝,會(huì)先與傳統(tǒng)的生命周期函數(shù)執(zhí)行起便。
2、與vue2相比,在vue3中對(duì)beforeDestroy和destroyed這兩個(gè)生命周期函數(shù)榆综,進(jìn)行了重命名妙痹,beforeUnmount 替換了 beforeDestroy;unmounted 替換了 destroyed鼻疮。
3细诸、setup()函數(shù),可以替代beforeCreate 和 created 這兩個(gè)生命周期函數(shù)陋守,因?yàn)関ue2中的beforeCreate和created生命周期的執(zhí)行幾乎與VUE3中的setup在同一時(shí)間執(zhí)行震贵。


image.png
<div class="child3">
  {{ count }}
  <button @click="updateCount">count++</button>
</div>
// 導(dǎo)入生命周期組合式api,除了beforeCreate和created這兩個(gè)生命周期函數(shù)沒有組合式api
// 其他的生命周期函數(shù)水评,都有對(duì)應(yīng)的組合式api猩系,命名方式只是在原有方法名的前面加上on
// setup()函數(shù)在這里充當(dāng)了beforeCreate和created這兩個(gè)生命周期函數(shù)的功能。
import { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount,onUnmounted } from "vue";
export default {
  name: "Child3",
  data() {
    return {
      show:true
    }
  },
  setup() {
    //注意:setup是在beforeCreate和created之前運(yùn)行的中燥。
    //所以寇甸,在setup里面,無法調(diào)用data和methods里面的數(shù)據(jù)
    console.log('setup');
    let count = ref(1);
    let updateCount = () => {
      count.value++;
    };
    //掛載前疗涉。
    onBeforeMount(() => {
        console.log('onBeforeMount');
    }),
    //掛載完成拿霉。在這個(gè)里面發(fā)送異步請(qǐng)求。調(diào)用接口咱扣。
    onMounted(()=>{
        console.log('onMounted');
    })
    //修改后绽淘,頁面重新掛載前
    onBeforeUpdate(()=>{
        console.log('onBeforeUpdate');
    })
    //修改后,頁面重新掛載完成
    onUpdated(()=>{
        console.log('onUpdated');
    })
    //卸載前
    onBeforeUnmount(()=>{
        console.log('onBeforeUnmount');
    })
    //卸載完成
    onUnmounted(() => {
        console.log('onUnmounted');
    })

    return {
      count,
      updateCount,
    };
  },
  /* data() {
    return {
      count: 1,
    };
  },
  methods: {
    updateCount() {
      this.count++;
    },
  }, */
  // 數(shù)據(jù)初始化前
  /*beforeCreate() {
    console.log("--beforeCreate--");
  },
  // 數(shù)據(jù)初始化完成
  created() {
    console.log("--created--");
  },
  // 頁面掛載前
  beforeMount() {
    console.log("--beforeMount--");
  },
  // 頁面掛載完成
  mounted() {
    console.log("--mounted--");
  },
  // 數(shù)據(jù)修改后闹伪,頁面重新掛載前
  beforeUpdate() {
    console.log(this.count);
    console.log("--beforeUpdate--");
  },
  // 數(shù)據(jù)修改后沪铭,頁面重新掛載完成
  updated() {
    console.log(this.count);
    console.log("--updated--");
  },
  // 卸載組件之前前
  beforeUnmount() {
    console.log("--beforeUnmount--");
  },
  // 卸載組件完成
  unmounted() {
    console.log("--unmounted--");
  }, */
};

三、toRef和toRefs

1偏瓤、toRef()函數(shù):可以用來為一個(gè) reactive 對(duì)象里面的指定屬性創(chuàng)建一個(gè) ref杀怠,這個(gè) ref 可以被傳遞并且能夠保持響應(yīng)性。這樣做的好處是簡化了模板中的表達(dá)式厅克。toRef()函數(shù)赔退,需要傳兩個(gè)參數(shù):reactive 對(duì)象、具體的屬性名证舟。
2硕旗、toRefs()函數(shù):把一個(gè)響應(yīng)式對(duì)象轉(zhuǎn)換成普通對(duì)象,該普通對(duì)象的每個(gè)屬性都是一個(gè) ref褪储。

<div class="child1">
  <ul>
    <li>姓名:{{ name }}</li>
    <li>年齡:{{ age }}</li>
    <li>性別:{{ sex }}</li>
    <li>地址:{{ address }}</li>
    <li>汽車名稱:{{ car.name }}</li>
    <li>汽車價(jià)格:{{ car.price }}</li>
    <li><button @click="updateStudent">修改學(xué)生信息</button></li>
  </ul>
</div>
import { reactive, toRefs } from "vue";
export default {
  name: "Child1",
  setup() {
    // 學(xué)生對(duì)象
    let student = reactive({
      name: "張三",
      age: 20,
      sex: "男",
      address: "南京",
      car: {
        name: "寶馬",
        price: 1000,
      },
    });
    // 修改學(xué)生的方法
    let updateStudent = () => {
      student.name = "李四";
      student.age = 22;
      student.sex = "女";
      student.address = "成都";
      student.car.name = "奔馳";
      student.car.price = 2000;
    };
    return {
      // toRef()方法卵渴,用于將一個(gè)reactive對(duì)象里面的指定屬性以ref形式的對(duì)象返回
      // name:toRef(student,'name'),
      // age:toRef(student,'age'),
      // sex:toRef(student,'sex'),
      // address:toRef(student,'address'),

      // 假如 reactive 對(duì)象中,有100個(gè)屬性鲤竹,上面的操作要寫100次浪读,所以昔榴,一般都直接用toRefs函數(shù)
      // 注意:如果student里面的屬性是一個(gè)對(duì)象,這個(gè)屬性對(duì)象里面的內(nèi)容是不能直接轉(zhuǎn)為ref的
      // toRefs只能保證一級(jí)屬性
      ...toRefs(student),
      updateStudent,
    };
  },
};

四碘橘、其他的組合式API

1互订、readonly

readonly()方法:用于返回一份只讀數(shù)據(jù)。傳入一個(gè)對(duì)象(響應(yīng)式或普通)或 ref痘拆,返回一個(gè)原始對(duì)象的只讀代理仰禽。一個(gè)只讀的代理是“深層的”,對(duì)象內(nèi)部任何嵌套的屬性也都是只讀的纺蛆。
注意:該方法吐葵,不能將一個(gè)普通值類型數(shù)據(jù)轉(zhuǎn)為只讀數(shù)據(jù)

<div>{{ student }} <button @click="updateStudent">修改學(xué)生信息</button></div>
import { reactive, readonly } from "vue";
export default {
  name: "Child2",
  setup() {
    let data = reactive({
      name: "張三",
      age: 20,
    });
    let student = readonly(data);
    // student是一個(gè)只讀對(duì)象,無法修改數(shù)據(jù)
    let updateStudent = () => {
      student.name = "李四";
      student.age = 22;
    };
    return {
      student,
      updateStudent,
    };
  },
};

2桥氏、isReadonly

檢查一個(gè)對(duì)象是否是由 readonly 創(chuàng)建的只讀代理温峭。

import { reactive, readonly, isReadonly } from "vue";
let data = reactive({
  name: "張三",
  age: 20,
});
let student = readonly(data);
console.log('student is readonly',isReadonly(student));   //true

3、isRef

isRef():檢查一個(gè)值是否為一個(gè) ref 對(duì)象字支。

import { ref, isRef } from "vue";
let name = ref('你好')
console.log('name is ref',isRef(name));   //true

4凤藏、isProxy

isProxy():檢查一個(gè)對(duì)象是否是由 reactive 或者 readonly 方法創(chuàng)建的代理。

import { reactive, readonly, isProxy } from "vue";
setup() {
let data = reactive({
  name: "張三",
  age: 20,
});
let student = readonly(data);
console.log('data is proxy',isProxy(data));   //true
console.log('student is proxy',isProxy(student));   //true

5堕伪、isReactive

isReactive():檢查一個(gè)對(duì)象是否是由 reactive 創(chuàng)建的響應(yīng)式代理揖庄。如果這個(gè)代理是由 readonly 創(chuàng)建的,但是又被 reactive 創(chuàng)建的另一個(gè)代理包裹了一層欠雌,那么同樣也會(huì)返回 true蹄梢。

import { reactive, isReactive } from "vue";
setup() {
  let data = reactive({
    name: "張三",
    age: 20,
  });
  console.log('data is reactive',isReactive(data));   //true
}

6、unref

unref()函數(shù):如果參數(shù)是一個(gè) ref 則返回它的 value桨昙,否則返回參數(shù)本身检号。等同于 val = isRef(val) ? val.value : val 。

import { ref, unref } from "vue";
setup() {
  let name = ref('你好')
  let age = 20
  console.log(unref(name));   // '你好'
  console.log(unref(age));   // 20
}

7蛙酪、markRaw

markRaw():使用markRaw()方法返回出來的對(duì)象,再也不能成為響應(yīng)式對(duì)象翘盖,函數(shù)返回這個(gè)對(duì)象本身桂塞。如果被 markRaw 標(biāo)記了,即使在響應(yīng)式對(duì)象中作屬性馍驯,也依然不是響應(yīng)式的阁危。

import { reactive, markRaw } from "vue";
setup() {
  // 使用markRaw()方法,返回出來的對(duì)象汰瘫,再也不能成為響應(yīng)式對(duì)象狂打。
  let car = markRaw({
      name:'奔馳',
      price:20
  })
  let car2 = reactive(car)
  // car2只是一個(gè)普通對(duì)象,不是響應(yīng)式對(duì)象
  console.log(car2);
}

8混弥、shallowRef

shallowRef():返回的對(duì)象 value 屬性值是 object對(duì)象(普通對(duì)象)趴乡,不再具備任何響應(yīng)式了。

<div>
  汽車信息:{{ car3 }}
  <button @click="updateCar">修改汽車</button>
</div>
import { shallowRef } from "vue";
setup() {
  let car3 = shallowRef({
    name: "大眾",
    type: {
      typeName: "SUV",
    },
  });
  let updateCar = () => {
    // 由于value返回的是object對(duì)象,所以晾捏,這里不再具有響應(yīng)式
    car3.value.name = "奔馳";
    car3.value.type.typeName = "跑車";
  };
  return {
    car3,
    updateCar
  };
}

9蒿涎、shallowReactive

shallowReactive():用于定義淺響應(yīng)式對(duì)象,只對(duì)第一層屬性設(shè)置響應(yīng)式惦辛。

import { shallowReactive,isReactive } from "vue";
setup() {
  let luhan = shallowReactive({
      name:'鹿晗',
      age:30,
      friend:{
          name:'關(guān)曉彤',
          age:20,
      }
  })
  let updateLuhan = ()=>{
      // luhan.name = '張藝興',
      // luhan.age = 25

      // 如果只是修改對(duì)象的深層屬性劳秋,不會(huì)觸發(fā)頁面更新
      luhan.friend.name = '小美'
      luhan.friend.age = 22
  }
}

10、shallowReadonly

shallowReadonly:淺只讀胖齐,只有第一層屬性是只讀的玻淑。

import { shallowReadonly } from "vue";
setup() {
  let luhan = shallowReactive({
      name:'鹿晗',
      age:30,
      friend:{
          name:'關(guān)曉彤',
          age:20,
      }
  })
  let luhan3 = shallowReadonly(luhan);
  // luhan3.name = '小明'      // 屬性只讀
  luhan3.friend.name = "小美";      // 屬性可修改
}

11、toRaw

toRaw()方法:用于將一個(gè)響應(yīng)式對(duì)象轉(zhuǎn)為普通對(duì)象呀伙。

import { toRaw } from "vue";
setup() {
  let luhan = shallowReactive({
      name:'鹿晗',
      age:30,
      friend:{
          name:'關(guān)曉彤',
          age:20,
      }
  })
  let luhan2 = toRaw(luhan);
  console.log("luhan2", luhan2);   // 普通對(duì)象
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末补履,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子区匠,更是在濱河造成了極大的恐慌干像,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驰弄,死亡現(xiàn)場離奇詭異麻汰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)戚篙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門五鲫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人岔擂,你說我怎么就攤上這事位喂。” “怎么了乱灵?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵塑崖,是天一觀的道長。 經(jīng)常有香客問我痛倚,道長规婆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任蝉稳,我火速辦了婚禮抒蚜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘耘戚。我一直安慰自己嗡髓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布收津。 她就那樣靜靜地躺著饿这,像睡著了一般浊伙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蛹稍,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天吧黄,我揣著相機(jī)與錄音,去河邊找鬼唆姐。 笑死拗慨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的奉芦。 我是一名探鬼主播赵抢,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼声功!你這毒婦竟也來了烦却?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤先巴,失蹤者是張志新(化名)和其女友劉穎其爵,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伸蚯,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摩渺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了剂邮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摇幻。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖挥萌,靈堂內(nèi)的尸體忽然破棺而出绰姻,到底是詐尸還是另有隱情,我是刑警寧澤引瀑,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布狂芋,位于F島的核電站,受9級(jí)特大地震影響憨栽,放射性物質(zhì)發(fā)生泄漏银酗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一徒像、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蛙讥,春花似錦锯蛀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翔曲。三九已至,卻和暖如春劈愚,著一層夾襖步出監(jiān)牢的瞬間瞳遍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工菌羽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掠械,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓注祖,卻偏偏與公主長得像猾蒂,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子是晨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容