Vue3 新特性

# Vue3的改進(jìn)及特點(diǎn)

1.性能的提升:打包大小減少 41%效诅,初次渲染快 55%师脂,更新快 133%澳腹,內(nèi)存使用減少 54%。

2.新推出的Composition API 使組件更易維護(hù)闻牡,減少無(wú)用數(shù)據(jù)綁定頁(yè)面更流暢。

4.更好TypeScript支持绳矩,可以在創(chuàng)建命令里直接配置罩润,頁(yè)面集成暢通無(wú)阻。

5.Teleport(瞬移組件)翼馆、Suspense(解決異步加載組件問(wèn)題)和全局 API 的修改和優(yōu)化割以。

6.Vue3兼容大部分Vue2的特性,用Vue2代碼開(kāi)發(fā)Vue3都可以应媚。

# 安裝

vue --version # 查看版本

注意:如果以前安裝過(guò)严沥,需要檢查一下版本,因?yàn)橹挥凶钚掳姹?V4.5.4 以上版本)才有創(chuàng)建 Vue3 的選項(xiàng)中姜。

npm install -g @vue/cli

使用 vue-cli 命令行創(chuàng)建項(xiàng)目

vue create vue3-1 // 根據(jù)提示自己選擇配置

啟動(dòng)命令

yarn serve 或 npm run serve

打包命令

yarn build 或 npm run build

# 新語(yǔ)法 setup(),ref(),reactive()

// 注:setup是為了優(yōu)化性能讓程序按需引入全局統(tǒng)一

1.用法一

<template>

? <div class="home">

? ? <div>名字:{{ name }}</div>

? ? <ul>

? ? ? <li v-for="item in list" :key="item" @click="show(item)">{{ item }}</li>

? ? </ul>

? </div>

</template>

<script lang="ts">

import { defineComponent, ref } from "vue";

// 注:defineComponent 在TypeScript下消玄,給予了組件正確的參數(shù)類型推斷

export default defineComponent({

? name: "Home",

? components: {},

? props:['msg'],

? setup(props,context) {

? ? // 注:setup函數(shù)是處于生命周期函數(shù) beforeCreate 和 Created 兩個(gè)鉤子函數(shù)之間的函數(shù) 也就說(shuō)在 setup 函數(shù)中是無(wú)法使用 data 和 methods 中的數(shù)據(jù)和方法跟伏,而methods等可以使用setup中return出去的數(shù)據(jù)。

? ? /*

? ? 一.函數(shù)的第一個(gè)參數(shù)是 props 用于接收 props.msg

? ? ? 這個(gè)props是一個(gè)響應(yīng)式的Proxy對(duì)象翩瓜,不可以解構(gòu)受扳,解構(gòu)后會(huì)失去響應(yīng),如果要用解構(gòu)的方式兔跌,要用toRefs

? ? ? let { msg } = toRefs(props) //但是解析成ref了要用msg.value,所以直接用props.msg更簡(jiǎn)單

? ? 二.context對(duì)象在setup()中暴露三個(gè)屬性 attrs 勘高、slots 和?emit 因?yàn)樵趕etup函數(shù)中還沒(méi)有創(chuàng)建Vue實(shí)例,是無(wú)法使用vm.$attrs坟桅、vm.$slots和vm.$emit的华望,所以這三個(gè)屬性充當(dāng)了這樣的作用,使用方法相同桦卒。

? ? 注意:

? ? ? context.attrs和vm.$attrts包含的是在實(shí)例vm.props中沒(méi)有被聲明識(shí)別的attribute(class和style除外)立美。所以setup()中參數(shù)props中暴露的變量,就不會(huì)在context.attrs中暴露方灾。

? ? ? context.slots和vm.$slots只能訪問(wèn)具名插槽建蹄,沒(méi)有命名的插槽或者v-slot:default的是沒(méi)有暴露的。

? ? ? context的attrs和slots是有狀態(tài)的裕偿,當(dāng)組件更新時(shí)也會(huì)實(shí)時(shí)更新洞慎,所以也不要解構(gòu)。但與props不同的是嘿棘,它們不是響應(yīng)式的劲腿,在setup()中的使用應(yīng)保持只讀的狀態(tài),如果要改變可以在onUpdated的周期函數(shù)中進(jìn)行鸟妙。

? ? ? context.emit和vm.$emit可以觸發(fā)實(shí)例上的監(jiān)聽(tīng)事件焦人。

? ? */

? ? const list = ref(["深圳", "北京", "上海"]);

? ? const name = ref("");

? ? //注:用ref是為了轉(zhuǎn)換成引用類型,讓全局引用保持一致重父,而之前原始類型是不行的花椭,所以要name.value的方示賦值

? ? const show = (index: string) => {

? ? ? ? name.value = index;

? ? };

? ? // 注:不return出去的數(shù)據(jù),模板是無(wú)法使用的房午。

? ? return {

? ? ? ? list,

? ? ? ? name,

? ? ? ? show

? ? };

? },

});

</script>

2.用法二 reactive() 優(yōu)化

<template>

? <div class="home">

? ? <div>名字:{{ data.name }}</div>

? ? <ul>

? ? ? <li v-for="item in data.list" :key="item" @click="data.show(item)">{{ item }}</li>

? ? </ul>

? </div>

</template>

<script lang="ts">

import { defineComponent, reactive } from "vue";

export default defineComponent({

? name: "Home",

? components: {},

? setup() {

? ? const data = reactive({

? ? ? list: ["深圳", "北京", "上海"],

? ? ? name: "",

? ? ? show: (index: string) => {

? ? ? ? data.name = index;

? ? ? },

? ? });

? ? return {

? ? ? data

? ? };

? },

});

</script>

2.用法三 toRefs() 優(yōu)化

<template>

? <div class="home">

? ? <div>名字:{{ name }}</div>

? ? <ul>

? ? ? <li v-for="item in list" :key="item" @click="show(item)">{{ item }}</li>

? ? </ul>

? </div>

</template>

<script lang="ts">

import { defineComponent,reactive,toRefs } from "vue";

export default defineComponent({

? name: "Home",

? components: {},

? setup() {

? ? const data = reactive({

? ? ? list: ["深圳", "北京", "上海"],

? ? ? name: "",

? ? ? show: (index: string) => {

? ? ? ? data.name = index;

? ? ? },

? ? });

? ? const refData = toRefs(data);

? ? //不能直接解析 ...data 必須用 toRefs()

? ? return {

? ? ? ...refData

? ? };

? },

});

</script>

# Vue3 生命周期函數(shù)用法, 需要引入 (注:vue2 生命周期函數(shù)不影響)

<script lang="ts">

import { defineComponent,ref,reactive,toRefs,

onBeforeMount,

onMounted,

onBeforeUpdate,

onUpdated,

onBeforeUnmount,

onUnmounted,

onActivated,

onDeactivated,

onErrorCaptured,

onRenderTracked,

onRenderTriggered

} from "vue";

export default defineComponent({

? name: "Home",

? components: {},

? setup() {

? ? //setup() 開(kāi)始創(chuàng)建組件之前矿辽,在beforeCreate和created之前執(zhí)行。

? ? const data = reactive({

? ? ? list: ["深圳", "北京", "上海"]

? ? });

? ? onBeforeMount(()=>{

? ? ? //組件掛載到節(jié)點(diǎn)上之前執(zhí)行的函數(shù)郭厌。

? ? })

? ? onMounted(()=>{

? ? ? //組件掛載完成后執(zhí)行的函數(shù)袋倔。

? ? })

? ? onBeforeUpdate(()=>{

? ? ? //組件更新之前執(zhí)行的函數(shù)

? ? })

? ? onUpdated(()=>{

? ? ? //組件更新完成之后執(zhí)行的函數(shù)。

? ? })

? ? onBeforeUnmount(()=>{

? ? ? //組件卸載之前執(zhí)行的函數(shù)折柠。

? ? })

? ? onUnmounted(()=>{

? ? ? //組件卸載完成后執(zhí)行的函數(shù)宾娜。

? ? })

? ? onActivated(()=>{

? ? ? //被包含在<keep-alive>中的組件,會(huì)多出兩個(gè)生命周期鉤子函數(shù)扇售。被激活時(shí)執(zhí)行碳默。

? ? })

? ? onDeactivated(()=>{

? ? ? //比如從 A 組件贾陷,切換到 B 組件缘眶,A 組件消失時(shí)執(zhí)行嘱根。

? ? })

? ? onErrorCaptured(()=>{

? ? ? //當(dāng)捕獲一個(gè)來(lái)自子孫組件的異常時(shí)激活鉤子函數(shù)。

? ? })

? ? //< 調(diào)試用生命函數(shù)

? ? onRenderTracked((event)=>{

? ? ? //跟蹤所有狀態(tài)觸發(fā)

? ? ? console.log(event);

? ? });

? ? onRenderTriggered((event) => {

? ? ? //跟蹤當(dāng)前狀態(tài)觸發(fā)

? ? ? console.log(event);

? ? ? //key 那邊變量發(fā)生了變化

? ? ? //newValue 更新后變量的值

? ? ? //oldValue 更新前變量的值

? ? ? //target 目前頁(yè)面中的響應(yīng)變量和函數(shù)

? ? });

? ? // 調(diào)試用生命函數(shù) />

? ? const refData = toRefs(data);

? ? return {

? ? ? ...refData

? ? };

? },

? mounted(){

? ? console.log("vue2 生命周期");

? }

});

</script>

# Vue3 watch用法

<script lang="ts">

import { defineComponent, ref, reactive, toRefs, watch } from "vue";

export default defineComponent({

? name: "Home",

? components: {},

? setup() {

? ? const text = ref("測(cè)試單個(gè)值");

? ? const data = reactive({

? ? ? list: ["深圳", "北京", "上海"],

? ? ? name: "",

? ? ? show: (index: string) => {

? ? ? ? data.name = index;

? ? ? },

? ? });

? ? //watch(text, 單個(gè)用法巷懈,watch([text,()=>data.name], 多個(gè)用法该抒,注:()=>data.name 為了兼容vue2

? ? watch([text,()=>data.name], (newValue, oldValue) => {

? ? ? console.log(`new--->${newValue}`);

? ? ? console.log(`old--->${oldValue}`);

? ? });

? ? const refData = toRefs(data);

? ? return {

? ? ? ...refData,

? ? };

? },

});

</script>

# Vue3 模塊化重用功能 (優(yōu)化 mixins)

1.新建useTime.ts文件

import { ref } from "vue";

const time = ref("00:00:00");

const getTime = () => {

? ? const now = new Date();

? ? const h= now.getHours() < 10 ? "0" + now.getHours() : now.getHours();

? ? const m = now.getMinutes() < 10 ? "0" + now.getMinutes() : now.getMinutes();

? ? const s= now.getSeconds() < 10 ? "0" + now.getSeconds() : now.getSeconds();

? ? time.value = h + ":" + m + ":" + s;

? ? setTimeout(getTime, 1000);

};

export { time, getTime }

2.引入

<template>

? <div class="home">

? ? <div>時(shí)間:{{time}} <button @click="startTime">開(kāi)始</button></div>

? </div>

</template>

<script lang="ts">

import { defineComponent, ref } from "vue";

import { time, getTime } from './useTime';

export default defineComponent({

? name: "Home",

? components: {},

? setup() {

? ? const startTime = () => {

? ? ? getTime();

? ? };

? ? return {

? ? ? startTime,

? ? ? time

? ? };

? },

});

</script>

# teleport 獨(dú)立掛載組件(解決樣式等沖突問(wèn)題不掛載到app下)

1. index.html 頁(yè)面新加插入點(diǎn)(會(huì)掛載到 #headTitie DOM下)

<div id="headTitie"></div>

<div id="app"></div>

2. 在components目錄下新建 headTitle.vue

<template>

? <teleport to="#headTitie">

? ? <div class="head">

? ? ? <h1>{{ title }}</h1>

? ? </div>

? </teleport>

</template>

<script lang="ts">

import { defineComponent, ref } from "vue";

export default defineComponent({

? name: "headTitie",

? setup() {

? ? const title = ref("Vue3 新特性示例");

? ? return {

? ? ? title,

? ? };

? },

});

</script>

3. 在 App.vue 加

<template>

? <headTitle />

? <router-view />

</template>

<script lang="ts">

import headTitle from "./components/headTitle.vue";

export default {

? name: "App",

? components: {

? ? headTitle,

? },

};

</script>

# Suspense 異步請(qǐng)求組件

1. 新建Demo.vue

<template>

? <div class="Demo">

? ? <div>名字:{{ name }}</div>

? </div>

</template>

<script lang="ts">

import { defineComponent } from "vue";

export default defineComponent({

? name: "Demo",

? components: {},

? setup() {

? ? return new Promise((resolve, reject) => {

? ? ? setTimeout(() => {

? ? ? ? return resolve({ name: "我是 Suspense 異步請(qǐng)求組件" });

? ? ? }, 2100);

? ? });

? },

});

</script>

2. 使用引入 home.vue

<template>

? <div class="home">

? ? <Suspense>

? ? ? <template #default>

? ? ? ? <Demo />

? ? ? </template>

? ? ? <template #fallback>

? ? ? ? <p>加載中...</p>

? ? ? </template>

? ? </Suspense>

? </div>

</template>

<script lang="ts">

import { defineComponent } from "vue";

import Demo from "./Demo.vue";

export default defineComponent({

? name: "Home",

? components: {Demo}

});

</script>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市顶燕,隨后出現(xiàn)的幾起案子凑保,更是在濱河造成了極大的恐慌,老刑警劉巖涌攻,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欧引,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡恳谎,警方通過(guò)查閱死者的電腦和手機(jī)芝此,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)因痛,“玉大人婚苹,你說(shuō)我怎么就攤上這事⊥腋啵” “怎么了膊升?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)谭企。 經(jīng)常有香客問(wèn)我廓译,道長(zhǎng),這世上最難降的妖魔是什么债查? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任非区,我火速辦了婚禮,結(jié)果婚禮上攀操,老公的妹妹穿的比我還像新娘院仿。我一直安慰自己,他們只是感情好速和,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布歹垫。 她就那樣靜靜地躺著,像睡著了一般颠放。 火紅的嫁衣襯著肌膚如雪排惨。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,255評(píng)論 1 308
  • 那天碰凶,我揣著相機(jī)與錄音暮芭,去河邊找鬼鹿驼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛辕宏,可吹牛的內(nèi)容都是我干的畜晰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼瑞筐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼凄鼻!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起聚假,我...
    開(kāi)封第一講書(shū)人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤块蚌,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后膘格,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體峭范,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年瘪贱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纱控。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡政敢,死狀恐怖其徙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情喷户,我是刑警寧澤唾那,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站褪尝,受9級(jí)特大地震影響闹获,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜河哑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一避诽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧璃谨,春花似錦沙庐、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至底扳,卻和暖如春铸抑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衷模。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工鹊汛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒲赂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓刁憋,卻偏偏與公主長(zhǎng)得像滥嘴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子职祷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

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