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


眾所周知,前端技術一直更新很快,這不 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)
 }
}

 


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM