助你上手Vue3全家桶之Vue3教程

前言

這些內(nèi)容是博主在學(xué)習(xí)過程中記錄下來的,有一些不重要的點(diǎn)就跳過了,需要時(shí)自行查詢文檔培他。其實(shí)V2V3的學(xué)習(xí)成本不高鹃两,熟悉V2的話,看完這篇文章就可以上手V3舀凛。

Vue3官網(wǎng)

在線源碼編譯地址

1俊扳,setup


setup是所有Composition API的容器,值為一個(gè)函數(shù)猛遍。組件中所用到的數(shù)據(jù)馋记、方法等等,均要配置在setup中螃壤,它會(huì)在beforeCreate之前執(zhí)行一次抗果,注意:V3this不再是指向Vue實(shí)例,訪問this會(huì)是undefined

1.1奸晴,返回值


  • 若返回一個(gè)對(duì)象冤馏,則對(duì)象中的屬性、方法, 在模板中均可以直接使用寄啼。
  • 若返回一個(gè)渲染函數(shù):則可以自定義渲染內(nèi)容逮光。

1.2,注意點(diǎn)


盡量不要與V2配置混用

V2配置(data墩划、methos涕刚、computed...)中可以訪問到setup中的屬性、方法乙帮。
但在setup中不能訪問到V2配置(data杜漠、methodscomputed...)察净。
如果有重名, setup優(yōu)先驾茴。

setup不能是一個(gè)async函數(shù)

因?yàn)榉祷刂挡辉?code>return的對(duì)象, 而是promise, 模板看不到return對(duì)象中的屬性。(后期也可以返回一個(gè)Promise實(shí)例氢卡,但需要Suspense和異步組件的配合)

1.3锈至,語法


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

export default {
    name: 'Home',
    setup(props, context) {
        const title = ref('標(biāo)題')
        const data = reactive({
            value: '哈哈哈'
        })
        return {
          title,
          data
        }
    }
}
</script>

1.4,setup的參數(shù)


  • props:值為對(duì)象译秦,包含組件外部傳遞過來峡捡,且組件內(nèi)部聲明接收了的屬性

  • context:上下文對(duì)象

    • attrs: 值為對(duì)象,包含組件外部傳遞過來筑悴,但沒有在props配置中聲明的屬性, 相當(dāng)于this.$attrs
    • slots: 收到的插槽內(nèi)容, 相當(dāng)于this.$slots
    • emit: 分發(fā)自定義事件的函數(shù), 相當(dāng)于this.$emit

2们拙,ref 創(chuàng)建響應(yīng)式數(shù)據(jù)


使用ref可以創(chuàng)建一個(gè)包含響應(yīng)式數(shù)據(jù)的引用對(duì)象(reference對(duì)象,簡(jiǎn)稱ref對(duì)象)阁吝,可以是基本類型睛竣、也可以是對(duì)象。

語法

// 創(chuàng)建
const xxx = ref(value)

// 使用
xxx.value

// 在模板中
<div>{{xxx}}</div>

3求摇,reactive 創(chuàng)建響應(yīng)式數(shù)據(jù)


定義一個(gè)對(duì)象類型的響應(yīng)式數(shù)據(jù)射沟,內(nèi)部基于ES6Proxy實(shí)現(xiàn)殊者,通過代理對(duì)象操作源對(duì)象內(nèi)部數(shù)據(jù)進(jìn)行操作

語法

// 創(chuàng)建
const xxx = reactive({
    xxx: ''
})

// 使用
xxx.xxx

4,computed 計(jì)算屬性


V2computed配置功能一致

語法

import { computed } from 'vue'

setup(){
    // 簡(jiǎn)寫語法
    let fullName = computed(() => {
        return person.firstName + '-' + person.lastName
    })
    
    // 完整語法
    let fullName = computed({
        get(){
            return person.firstName + '-' + person.lastName
        },
        set(value){
            const nameArr = value.split('-')
            person.firstName = nameArr[0]
            person.lastName = nameArr[1]
        }
    })
    
    return fullName
}

5验夯,watch 監(jiān)聽


V2watch配置功能一致猖吴,語法有點(diǎn)改動(dòng)

語法

  • 情況一:監(jiān)視ref定義的響應(yīng)式數(shù)據(jù)
watch(sum, (newValue, oldValue) => {
    console.log('sum變化了', newValue, oldValue)
}, {immediate:true})
  • 情況二:監(jiān)視多個(gè)ref定義的響應(yīng)式數(shù)據(jù)
watch([sum, msg], (newValue,oldValue) => {
    console.log('sum或msg變化了', newValue,oldValue)
}) 
  • 情況三:監(jiān)視reactive定義的響應(yīng)式數(shù)據(jù)
// 若watch監(jiān)視的是reactive定義的響應(yīng)式數(shù)據(jù),則無法正確獲得oldValue
// 若watch監(jiān)視的是reactive定義的響應(yīng)式數(shù)據(jù)挥转,則強(qiáng)制開啟了深度監(jiān)視
watch(person, (newValue, oldValue) => {
    console.log('person變化了', newValue, oldValue)
}, { immediate:true, deep:false }) // 此處的deep配置不再奏效
  • 情況四:監(jiān)視reactive定義的響應(yīng)式數(shù)據(jù)中的某個(gè)屬性
watch(() => person.job, (newValue, oldValue) => {
    console.log('person的job變化了', newValue, oldValue)
}, { immediate:true, deep:true }) 
  • 情況五:監(jiān)視reactive定義的響應(yīng)式數(shù)據(jù)中的某些屬性
watch([() => person.job, () => person.name], (newValue, oldValue) => {
    console.log('person的job變化了', newValue, oldValue)
}, { immediate:true, deep:true })
  • 特殊情況:此處由于監(jiān)視的是reactive素定義的對(duì)象中的某個(gè)屬性海蔽,所以deep配置有效
watch(() => person.job, (newValue, oldValue) => {
    console.log('person的job變化了', newValue, oldValue)
}, { deep:true })

6,watchEffect 監(jiān)聽回調(diào)


watch的區(qū)別是绑谣,watch既要指明監(jiān)視的屬性党窜,也要指明監(jiān)視的回調(diào)。而watchEffect借宵,不用指明監(jiān)視哪個(gè)屬性幌衣,監(jiān)視的回調(diào)中用到哪個(gè)屬性,那就監(jiān)視哪個(gè)屬性壤玫,不用寫返回值豁护。

語法

// 回調(diào)中用到的數(shù)據(jù)只要發(fā)生變化,則直接重新執(zhí)行回調(diào)
watchEffect(() => {
    const x1 = sum.value
    const x2 = person.age
    console.log('watchEffect配置的回調(diào)執(zhí)行了')
})

7欲间,生命周期


生命周期全都寫在setup

7.1楚里,改變


  • beforeDestroy 改名為 beforeUnmount
  • destroyed 改名為 unmounted
  • beforeCreate => setup
  • created => setup
  • beforeMount => onBeforeMount
  • mounted => onMounted
  • beforeUpdate => onBeforeUpdate
  • updated => onUpdated
  • beforeUnmount => onBeforeUnmount
  • unmounted => onUnmounted

7.2,語法


setup() {
    onMounted(() => {
      console.log('mounted')
    })
}

8猎贴,toRef 創(chuàng)建ref


創(chuàng)建一個(gè)ref對(duì)象班缎,其value值指向另一個(gè)對(duì)象中的某個(gè)屬性

語法

const state = reactive({
  foo: 1,
  bar: 2
})

const fooRef = toRef(state, 'foo')

// 傳遞props
export default {
  setup(props) {
    useSomeFeature(toRef(props, 'foo'))
  }
}

9,toRefs 響應(yīng)式轉(zhuǎn)換


將響應(yīng)式對(duì)象轉(zhuǎn)換為普通對(duì)象她渴,其中結(jié)果對(duì)象的每個(gè)property都是指向原始對(duì)象相應(yīng)propertyref

語法

const state = reactive({
  foo: 1,
  bar: 2
})

const stateAsRefs = toRefs(state)
// 此時(shí)state和stateAsRefs是關(guān)聯(lián)的

10达址,shallowReactive 響應(yīng)式外層轉(zhuǎn)換


只處理對(duì)象最外層屬性的響應(yīng)式(淺響應(yīng)式)。適用于:一個(gè)對(duì)象數(shù)據(jù)惹骂,結(jié)構(gòu)比較深, 但變化時(shí)只是外層屬性變化

語法

const state = shallowReactive({
  foo: 1,
  nested: {
    bar: 2
  }
})

11苏携,shallowRef 基本數(shù)據(jù)響應(yīng)式


只處理基本數(shù)據(jù)類型的響應(yīng)式, 不進(jìn)行對(duì)象的響應(yīng)式處理做瞪。適用于:一個(gè)對(duì)象數(shù)據(jù)对粪,后續(xù)功能不會(huì)修改該對(duì)象中的屬性,而是生新的對(duì)象來替換

語法

const shallow = shallowRef({
  greet: 'Hello, world'
})

12装蓬,readonly 響應(yīng)式變只讀


讓一個(gè)響應(yīng)式數(shù)據(jù)變?yōu)橹蛔x的(深只讀)著拭,應(yīng)用于不希望數(shù)據(jù)被修改時(shí)

語法

const shallow = shallowRef({
  greet: 'Hello, world', // 只讀
  nested: {
    bar: 2 // 只讀
  }
})

13,shallowReadonly 響應(yīng)式變只讀


讓一個(gè)響應(yīng)式數(shù)據(jù)變?yōu)橹蛔x的(淺只讀)牍帚,應(yīng)用于不希望數(shù)據(jù)被修改時(shí)

語法

const shallow = shallowReadonly({
  foo: 1, // 只讀
  nested: {
    bar: 2 // 非只讀
  }
})

14儡遮,toRaw 響應(yīng)式變非響應(yīng)式


將一個(gè)由reactive生成的響應(yīng)式對(duì)象轉(zhuǎn)為普通對(duì)象,對(duì)這個(gè)普通對(duì)象的所有操作暗赶,不會(huì)引起頁面更新鄙币。

語法

const foo = {}
const Foo = reactive(foo)
console.log(toRaw(Foo) === foo) // true

15肃叶,markRaw 標(biāo)記永遠(yuǎn)不響應(yīng)式


標(biāo)記一個(gè)對(duì)象,使其永遠(yuǎn)不會(huì)再成為響應(yīng)式對(duì)象十嘿,有些值不應(yīng)被設(shè)置為響應(yīng)式的因惭,例如復(fù)雜的第三方類庫等,當(dāng)渲染具有不可變數(shù)據(jù)源的大列表時(shí)绩衷,跳過響應(yīng)式轉(zhuǎn)換可以提高性能蹦魔。

語法

const foo = markRaw({})
console.log(isReactive(reactive(foo))) // false

// 嵌套在其他響應(yīng)式對(duì)象中時(shí)也可以使用
const bar = reactive({ foo })
console.log(isReactive(bar.foo)) // false

16,customRef 依賴更新控制


創(chuàng)建一個(gè)自定義的 ref咳燕,并對(duì)其依賴項(xiàng)跟蹤和更新觸發(fā)進(jìn)行顯式控制勿决。它需要一個(gè)工廠函數(shù),該函數(shù)接收tracktrigger函數(shù)作為參數(shù)招盲,并且應(yīng)該返回一個(gè)帶有getset的對(duì)象低缩。

語法

<script>
import { customRef } from 'vue'

export default {
    name: 'Home',
    setup() {
        // 實(shí)現(xiàn)防抖函數(shù)
        const fn = function(value, delay = 500) {
            let timeout
            return customRef((track, trigger) => {
                return {
                    get() {
                        track()
                        return value
                    },
                    set(newValue) {
                        clearInterval(timeout)
                        timeout = setTimeout(() => {
                            console.log(newValue)
                            value = newValue
                            trigger()
                        }, delay)
                    }
                }
            })
        }
        const keyword = fn('', 500)
        return {
            keyword
        }
    }
}
</script>

17,provide & inject 通信


實(shí)現(xiàn)祖與后代組件間通信宪肖,父組件有一個(gè)provide選項(xiàng)來提供數(shù)據(jù)表制,后代組件有一個(gè)inject選項(xiàng)來開始使用這些數(shù)據(jù)

語法

// 祖組件
setup(){
    let car = reactive({ name:'奔馳', price:'40萬' })
    provide('car', car)
}

// 后代組件
setup(props, context){
    const car = inject('car')
    return { car }
}

18,響應(yīng)式數(shù)據(jù)的判斷


18.1控乾,isRef


檢查一個(gè)值是否為一個(gè)ref對(duì)象

語法

const val = ref('xxx')
isRef(val) // true

18.2么介,isReactive


檢查一個(gè)值是否為一個(gè)isReactive對(duì)象

語法

const val = isReactive({})
isRef(val) // true

18.3,isReadonly


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

語法

const state = reactive({
  name: 'John'
})
console.log(isReactive(state)) // true

18.4蜕衡,isProxy


檢查對(duì)象是否是由reactivereadonly創(chuàng)建的proxy

語法

const state = reactive({
  name: 'John'
})
console.log(isProxy(state)) // true

19壤短,teleport 移動(dòng)dom組件


Teleport提供了一種干凈的方法,允許我們控制在DOM中哪個(gè)父節(jié)點(diǎn)下渲染了HTML慨仿,而不必求助于全局狀態(tài)或?qū)⑵洳鸱譃閮蓚€(gè)組件久脯。

語法

<teleport to="移動(dòng)位置">
    <div v-if="isShow" class="mask">
        <div class="dialog">
            <h3>我是一個(gè)彈窗</h3>
            <button @click="isShow = false">關(guān)閉彈窗</button>
        </div>
    </div>
</teleport>


// to的格式
<teleport to="#some-id" />
<teleport to=".some-class" />
<teleport to="[data-teleport]" />

// disabled的格式
<teleport to="#popup" :disabled="displayVideoInline">
  <video src="./my-movie.mp4">
</teleport>

20,Suspense 異步渲染組件


等待異步組件時(shí)先渲染一些額外內(nèi)容镰吆,讓應(yīng)用有更好的用戶體驗(yàn)

語法

<template>
    <div class="app">
        <h3>我是App組件</h3>
        <Suspense>
            <template #default>
                <Child/>
            </template>
            <template #fallback>
                <h3>加載中.....</h3>
            </template>
        </Suspense>
    </div>
</template>


import { defineAsyncComponent } from 'vue'
const Child = defineAsyncComponent(() => import('./components/Child.vue'))

components: {
    Child
}

21帘撰,全局API調(diào)整


將全局的API,即:Vue.xxx調(diào)整到應(yīng)用實(shí)例(app)上

V2的api V3的api
Vue.config.xxxx app.config.xxxx
Vue.component app.component
Vue.directive app.directive
Vue.mixin app.mixin
Vue.use app.use
Vue.prototype app.config.globalProperties

22万皿,移除api


名稱 現(xiàn)狀
Vue.config.productionTip 已移除
config.keyCodes 已移除
$children 已移除
$listeners 已移除
$on 已移除
$off 已移除
$once 已移除
filters 已移除
.native 已移除

23摧找,Ref 獲取DOM


由于V3中不在存在this,所以ref的獲取調(diào)整了

23.1牢硅,單個(gè)ref


語法

<div ref="Qrcode" class="qr_codeode_url" />

import { ref } from 'vue'

export default {
  setup() {
    const Qrcode = ref(null)
    // 掛載后
    onMounted(() => {
        console.log(Qrcode.value)
    })
    return {
      Qrcode
    }
  }
}

23.2蹬耘,循環(huán)中的ref


V3中在for循環(huán)元素上綁定ref將不再自動(dòng)創(chuàng)建$ref數(shù)組。要從單個(gè)綁定獲取多個(gè)ref减余,請(qǐng)將ref綁定到一個(gè)更靈活的函數(shù)上

語法

<div v-for="item in list" :ref="setItemRef"></div>

import { onBeforeUpdate, onUpdated } from 'vue'

export default {
  setup() {
    let itemRefs = []
    const setItemRef = el => {
      if (el) {
        itemRefs.push(el)
      }
    }
    onBeforeUpdate(() => {
      itemRefs = []
    })
    onUpdated(() => {
      console.log(itemRefs)
    })
    return {
      setItemRef
    }
  }
}
  • itemRefs不必是數(shù)組:它也可以是一個(gè)對(duì)象综苔,其ref可以通過迭代的key被設(shè)置
  • 如有需要,itemRef也可以是響應(yīng)式的,且可以被偵聽

24如筛,emits 自定義事件


定義一個(gè)組件可以向其父組件觸發(fā)的事件

// 在子組件中
<h1 @click="father">{{ msg }}</h1>

export default {
    name: 'HelloWorld',
    props: {
        msg: {
            type: String,
            default: ''
        }
    },
    emits: ['close'],
    setup(props, { emit }) {
        const father = function() {
            emit('close', 'child')
        }
        return {
            father
        }
    }
}

// 在父組件中
<HelloWorld :msg="msg" @click="fn" @close="fn2" />

25堡牡,$nextTick 異步更新


使用方式修改

import { nextTick } from 'vue'

nextTick(() => {
  // ...
})

26,hook 生命周期事件


通過事件來監(jiān)聽組件生命周期中的關(guān)鍵階段

語法

// V2的語法
<template>
  <child-component @hook:updated="onUpdated">
</template>

// V3的語法
<template>
  <child-component @vnode-updated="onUpdated">
</template>

// 駝峰寫法
<template>
  <child-component @vnodeUpdated="onUpdated">
</template

如果看了覺得有幫助的杨刨,我是@鵬多多11997110103悴侵,歡迎 點(diǎn)贊 關(guān)注 評(píng)論;
END

PS:在本頁按F12拭嫁,在console中輸入document.querySelectorAll('._2VdqdF')[0].click()可免,有驚喜哦

往期文章

個(gè)人主頁

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市怕品,隨后出現(xiàn)的幾起案子妇垢,更是在濱河造成了極大的恐慌,老刑警劉巖肉康,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闯估,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡吼和,警方通過查閱死者的電腦和手機(jī)涨薪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炫乓,“玉大人刚夺,你說我怎么就攤上這事∧┑罚” “怎么了侠姑?”我有些...
    開封第一講書人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)箩做。 經(jīng)常有香客問我莽红,道長(zhǎng),這世上最難降的妖魔是什么邦邦? 我笑而不...
    開封第一講書人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任安吁,我火速辦了婚禮,結(jié)果婚禮上圃酵,老公的妹妹穿的比我還像新娘柳畔。我一直安慰自己馍管,他們只是感情好郭赐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般捌锭。 火紅的嫁衣襯著肌膚如雪俘陷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評(píng)論 1 304
  • 那天观谦,我揣著相機(jī)與錄音拉盾,去河邊找鬼。 笑死豁状,一個(gè)胖子當(dāng)著我的面吹牛捉偏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播泻红,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼夭禽,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了谊路?” 一聲冷哼從身側(cè)響起讹躯,我...
    開封第一講書人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缠劝,沒想到半個(gè)月后潮梯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惨恭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年秉馏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脱羡。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沃饶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出轻黑,到底是詐尸還是另有隱情糊肤,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布氓鄙,位于F島的核電站馆揉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏抖拦。R本人自食惡果不足惜升酣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望态罪。 院中可真熱鬧噩茄,春花似錦、人聲如沸复颈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至凿菩,卻和暖如春机杜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衅谷。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來泰國打工椒拗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人获黔。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓蚀苛,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親玷氏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枉阵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

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

  • 1,前言 本文主要講開發(fā)過程中需要常用的预茄,有些api不常用兴溜,需要的時(shí)候可以自行查找文檔。因?yàn)閂3中沒有了this耻陕,...
    鵬多多閱讀 1,119評(píng)論 0 1
  • Vue3快速上手 1.Vue3簡(jiǎn)介 2020年9月18日拙徽,Vue.js發(fā)布3.0版本,代號(hào):One Piece(海...
    冷r閱讀 2,932評(píng)論 1 38
  • Vue3快速上手 1.Vue3簡(jiǎn)介 2020年9月18日诗宣,Vue.js發(fā)布3.0版本膘怕,代號(hào):One Piece(海...
    不再猶豫_c61b閱讀 460評(píng)論 0 0
  • 全局API createApp 返回一個(gè)提供應(yīng)用上下文的應(yīng)用實(shí)例。應(yīng)用實(shí)例掛載的整個(gè)組件樹共享同一個(gè)上下文召庞。 de...
    WangLizhi閱讀 2,497評(píng)論 0 0
  • 大家好篮灼,我是前端嵐楓忘古,一枚二線城市的程序媛,上篇主要跟分享了《VUE系列-Vue中組件的應(yīng)用(三)[https:/...
    前端嵐楓閱讀 983評(píng)論 0 0