Vue3 中有哪些值得深究的知識點?

前端人發表於2021-12-07

眾所周知,前端技術一直更新很快,這不 vue3 也問世這麼久了,今天就來給大家分享下vue3中值得注意的知識點。喜歡的話建議收藏,點個關注!


1、createApp

vue2 和 vue3 在建立例項時,有很大的區別,具體對比如下:

//Vue 2
Vue.use({
 router,
 store,
  render:h=>h(App)
}).$mount("#app")

//Vue 3
createApp(App).use(router).use(store).mount("#app")

 

vue2 建立例項,使用的是 new Vue() 對應的 router、store 都是其中一部分引數。

而 vue3 中,使用 createApp 建立應用例項,router、store 被當作外掛通過鏈式呼叫。

在 vue2 中,建立多個例項的話,如果有 mixin、prototype 等時,容易造成例項汙染。而 createApp 方法建立的是一個全新的例項,可以有效地避免這個問題。所以在vue3中,可以任意地建立多個例項。

2、setup

vue2 中選項式開發的,而 vue3 採用組合式開發,也可以向下相容選項式開發。

setup 函式就是 vue3 中 Composition API 的入口,是處於生命週期鉤子函式 beforeCreate 和 created 兩個函式之間,所以 setup 中的屬性和方法無法在外部使用。如果需要使用的話,必須 return 暴露出去。

對比一下 vue2 和 vue3 中 data 和 method 使用區別:

// vue2
export default{
 data(){
  return{
   name:"熱愛前端的小姐姐"
  },
  methods:{
   print(){
    console.log("列印")
   }
  }
 }
}

// vue3
export default{
 setup(){
  const name="熱愛前端的小姐姐"
  function print(){
   console.log("列印")
  }
  return {  name , print }
 }
}

 

vue2 中,this 是我們的常客,隨處可見它的蹤影。我們在 setup 中加入 this 的列印,試著檢視下結果,發現執行結果是 undefined。

所以在 setup 內無法使用 this 以及掛載 this 相關的東西。

所以 setup 函式提供了兩個引數:

setup(props,context){
 //props 是響應式資料,不能直接解構賦值
 //context 非響應式物件,可以直接解構使用
  
 // Attribute (非響應式物件)
 console.log(context.attrs)
 
 // 插槽 (非響應式物件)
 console.log(context.slots)
 
// 觸發事件 (方法)
console.log(context.emit)
}

 

3、script setup 語法糖

簡化上述 setup 組合式 API 的寫法,屬於 vue3 的新語法糖。

特點:

  1. 定義的屬性和方法無需 return,可以直接使用。
  2. 自動註冊元件,不再需要 components 內註冊元件。

大大簡化上述 setup() 的程式碼。

4、鉤子函式

vue2 使用生命週期函式時,直接使用就好了。如:

// vue2
export default{
 beforeCreate(){
 },
 mounted(){
  
 }
}

 

但是在 vue3 組合式 API 中,通過生命週期鉤子前面加 on 來訪問,使用之前必須引入。如:

// vue3 
<script setup>
 import { onMounted } from "vue"
 onMounted(()=>{
 
 })
</script>

 

由於 setup 是圍繞 beforeCreate 和 created 生命週期鉤子執行的,所以在 setup 內不需要這兩個鉤子函式,剩餘的都是一樣的。

官方提供生命週期鉤子:

Vue3 中有哪些值得深究的知識點?

 

5、teleport 傳送門

teleport 傳送門可以把內部的元素繫結到任意父元素上,使用方式簡單靈活。

使用方式:

<teleport to="body"></teleport>

 

to 屬性是指定 teleport 中內容加入的 DOM 元素,可以是標籤名、類名或 id 。

//標籤名  。上述例項就是加入body元素內,使用的是標籤名。
<teleport to="body"></teleport>

//類名。如:to=".className"
<teleport to=".className"></teleport>

//id名
<teleport to="#idName"></teleport>

 

優點:多個元件巢狀層次過多時,樣式層級處理麻煩,使用 teleport 可以把元素剝離出來,設定樣式方便,同時 vue 控制狀態也方便。

6、mixin 混入

mixin 物件會把多個元件公用的選項提取出來,需要的元件內引入,管理方便。在 vue3 中 mixin 使用較少。

使用方式:

<script>
const myMixin = {
 data(){
  return {name:'熱愛前端的小姐姐'}
 }
}
export default {
 mixins:[myMixin],
 data(){
  return {
   qdr:"前端人"
  }
 }
}
</script>

 

使用時,可以引入多個 mixin 物件。使用注意事項:

  1. mixin 物件與元件包含相同選項時,會自動合併。
  2. mixin 物件與元件相同選項內擁有相同屬性時,就近原則,優先繼承例項內的值。
  3. mixin 和元件包含相同的鉤子函式時,會合並執行,優先執行 mixin 中的鉤子函式。
  4. mixin 自定義屬性與例項中衝突時,可以通過 optionMergeStrategies 定義優先順序。

7、自定義指令

全域性自定義指令:

vue2 的 directive 掛載到 Vue 物件上。

vue3 的 directive 掛載到 app 上,如:

//Vue 2
Vue.directive('name',opt)

//Vue 3
const app = createApp(App)
app.directive("name",options)
app.mount("#app")

 

區域性自定義指令:與 vue2 寫法相同。

在 vue3 中自定義指令生命週期鉤子函式有一部分改變,鉤子函式分別為:

  • created
  • beforeMounted
  • mounted
  • beforeUpdate
  • updated
  • beforeUnmounted
  • unmounted

8、ref、reactive

ref 作用是讓基礎型別資料具備響應式。

reactive 讓引用資料型別具備響應式能力。

ref 和 reactive 包裹資料,使資料具備響應式,在使用之前需要先引入。

使用方法如:

<script setup>
 import { ref , reactive } from "vue"
 let mood = ref("value")
 let me = reactive({
  str:value,
 })
</script>

 

 

setup + ref + reactive 就可以實現 vue2 中 data 的響應式功能,所以 setup 能夠替換掉 data 。

9、toRefs、toRef

toRefs 解構 props 傳遞的資料,由於父向子元件通過 props 傳值是響應式的,使用 ES6 解構會消除響應特性,所以使用 toRefs 。

<script setup>
 const props = defineProps({
  selectNum:Number,
  allNum:Number,
 })
 const { selectNum, allNum } = toRefs(props)
</script>

 

toRef 也是解構資料,主要是對可選引數處理,執行時先檢查 解構的資料中是否存在該屬性,如果存在就繼承,不存在則會建立一個屬性,這樣就不會報錯了。

const str = toRef( props, 'str' )

 

10、watch、watchEffect 新用法

watch 、watchEffect 都是偵聽器。

watch 會監聽某個基礎型別資料或引用資料型別的某個具體屬性。

vue3 使用 watch 之前,必須引入。

//vue2
watch:{
 mood(curVal,preVal){
  console.log('cur',curVal);//最新值
  console.log('pre',preVal);//修改之前的值
 }
}

//vue3
import { watch } from "vue"
watch(
 name ,
 ( curVal , preVal )=>{ //業務處理  },
 options
)

 

watchEffect 監聽的是引用資料型別的所有屬性,不需要指定是哪個具體的屬性,一旦執行,就會立刻執行。

watchEffect 使用之前也必須引入。

import { watchEffect } from "vue"
let obj = reactive({ name:'qq',sex:'女'})
watchEffect(() => {
 console.log('name',obj.name);
 console.log('sex' , obj.sex);
})

 

watch 與 watchEffect 對比:

  1. watch 執行的時候不會立刻執行, watchEffect 立即執行。
  2. watch 更加具體,需要指定監聽的誰,watchEffect 不要執行具體監聽誰,回撥函式內直接使用就可以,比較抽象。
  3. watch 回撥內可以訪問到修改之前的值,watchEffect 只能訪問最新的值。
  4. watch 可通過配置實現 watchEffect 的前兩個特性。

11、computed 新用法

computed 計算屬性

選項式 API 中 vue2 和 vue3 使用相同。

組合式 API 中,使用之前需要引入。

// 選項式
computed:{
 sum(){
  return this.num1+ this.num2
 }
}

//組合式
import { ref, computed } from "vue"
export default{
 setup(){
  const num1 = ref(1)
  const num2 = ref(1)
  let sum = computed(()=>{
   return num1.value + num2.value
  })
 }
}

 

或者,它可以使用一個帶有 get 和 set 函式的物件來建立一個可寫的物件。

let mul = computed({
 get:()=>{
  return num1.value *10
 },
 set:(value)=>{
  return num1.value = value/10
 }
})

 

在vue3.2+內,computed 可接受一個帶有 onTrack 和 onTrigger 選項的物件作為第二個引數:

  • onTrack 會在某個響應式 property 或 ref 作為依賴被追蹤時呼叫。
  • onTrigger 會在偵聽回撥被某個依賴的修改觸發時呼叫。

12、provide / inject

provide/inject 類似於訊息的訂閱和釋出,provide 提供或傳送資料或方法, inject 接收資料或方法。

優點:元件巢狀層級較多,父元件向子元件、多個孫元件傳值時,傳遞資料需要一級一級向下傳遞,比較麻煩,使用 project 和 inject 很方便地解決了這個問題。

//vue2
export default{
 provide:{
  info:"提供資料"
 }
}
//接收資料
export default{
 inject:['info'],
 mounted(){
     console.log("接收資料:", this.info) // 接收資料:提供資料
 }
} 

//vue3
<script setup>
 import { provide } from "vue"
 provide( 'info', "值" )
</script>
//接收資料
<script setup>
 import { inject } from "vue"
 const info = inject( 'info', "設定預設值" )
</script>

 

13、readonly

readonly 只讀函式,使用之後該資料只能使用,不能修改,修改時會有警告。

父子元件之間傳值時,如果傳遞的是響應式資料,子元件修改的時候,父元件的也會更新,這樣就容易造成狀態混亂,不符合 vue 的單項資料流。

如果使用 readonly ,保證資料在其他元件內只能使用,並不能修改,規避混亂。

14、獲取真實DOM

vue2 使用 $ref 獲取真實DOM。

vue3 使用 ref 獲取真實DOM。與上述的 ref 不同。

<div ref="box" class="test" id="boxtest">獲取真實DOM</div>

//vue2
<script>
 export default{
  mounted(){
   console.log('box', this.$refs.box);
  }
 }
</script>

//vue3
<script setup>
 const box = ref(null)
  onMounted(()=>{
  console.log('box',box.value);
 })  
</script>

 

15、vue3 中的 vuex4

createStore 函式建立新的 store 例項。使用之前需要先引入。

import { createApp } from 'vue'
import App from './App.vue'
import { createStore } from "vuex"

const store = createStore({
 state(){
  return{
   num:1,
  }
 }
})

const app = createApp(App)
app.use(store)
app.mount('#app')

 

元件內使用 store 時,通過 useStore 引入,使用之前也需要引入。

import { useStore } from "vuex"
const store = useStore()

 

使用的時候,與低版本都是一樣的。使用 state 內資料時,可以通過 toRefs 解構。

16、v-slot

v-slot 指令只能用在 template 或元件上,否則就會報錯。

簡化 slot、slot-scope 作用域插槽的功能,相比更加強大,程式碼效率更高。

使用:

<child-com>
 <template v-slot:header>
  頭部
 </template>
 <template v-slot:body>
  內容
 </template>
</child-com>

 

簡寫:

<child-com>
 <template #header>
  頭部
 </template>
 <template #body>
  內容
 </template>
</child-com>

 

17、vue3 中的 vue-router4

createRouter 建立 router 例項,之前的 mode 改為 history 。

import { createRouter,createWebHashHistory } from "vue-router";

const routes = []

const router = createRouter({
 history:createWebHashHistory('/'),
 routes
})

export default router

 

在 main.js 內引入的時候,通過 use 引用。

import { createApp } from 'vue'
import App from './App.vue'
import router from "./router/index"

const app = createApp(App)
app.use(router)
app.mount('#app')

 

關於 vue-router4 更新挺多的,更多知識請閱讀《 vue-router 4 你真的熟練嗎?》文章。

18、render

在 vue3 中,render 函式的引數發生了改變,之前的 h 去掉,變成全域性引入,虛擬節點具備扁平的屬性結構。

vue3中 render 應用

import { h } from "vue"
export default {
 render(){
  return h("div", {}, content)
 }
}

 


好了小編今天的文章就到此結束了,喜歡我的可以點個關注哦

相關文章