成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

整理分享經典技巧之vue3及與vue2的區別(部分)

本篇文章給大家帶來了vue3與vue2的部分區別的相關知識,其中包括生命周期變化、實例變化以及方法變化等等,希望對大家有幫助。

整理分享經典技巧之vue3及與vue2的區別(部分)

1.生命周期的變化:3.x(上) 2.x(下)

整理分享經典技巧之vue3及與vue2的區別(部分)
整理分享經典技巧之vue3及與vue2的區別(部分)

不難看出,vue3.0與vue2.0之間生命周期函數在銷毀的時候有變化:

beforeDestroy --> beforeUnmount destroyed --> unmounted
其他的區別主要在于書寫使用的語言上的差別 在ts中使用 class 類組件書寫可以 參考 vue-class-component 或者 vue-property-decorator 書寫的風格和vue2.0的選項式區別不大。 如果使用js書寫代碼 則應當使用組合式。

具體變化帶來的問題,會在下面的組合式寫法中講解。

2.定義全局變量的方法變化

// 之前(Vue 2.x) Vue.prototype.$http = () => {} Vue.prototype.url= 'http://123' // 之后(Vue 3.x) const app = createApp({}) app.config.globalProperties.$http = () => {} app.config.globalProperties.url= 'http://123'

3.創建vue實例變化

//=======vue3.x //使用createApp函數來實例化vue, //該函數接收一個根組件選項對象作為第一個參數 //使用第二個參數,我們可以將根 prop 傳遞給應用程序 import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' createApp(App,{ userName: "blackLieo" }) .use(store) .use(router) .mount('#app')   //由于 createApp 方法返回應用實例本身,因此可以在其后鏈式調用其它方法,這些方法可以在以下部分中找到。  //=======vue2.x import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store'  Vue({   router,   store,   render: h => h(App) }).$mount('#app')

4.插槽使用變化

//================vue2.0使用插槽基本上直接使用slot進行操作//其中vue2.0經歷了兩次更迭,2.6.0版本slot升級為v-slot<p>     <slot :current="toolTipData" name="test"></slot> // 具名 作用域插槽     <slot></slot> //默認插槽</p>//父組件調用該組件<test>     <template>        <p>默認插槽</p>     </template>     // 作用域插槽     <template slot-scope="{ current }" slot="test">        <el-form label-width="80px" :model="current">          <el-form-item label="id:">            <el-link type="info">{{ current.id }}</el-link>          </el-form-item>          <el-form-item label="name:">            <el-link type="info">{{ current.name }}</el-link>          </el-form-item>          <el-form-item label="label:">            <el-link type="info">{{ current.label }}</el-link>          </el-form-item>          <el-form-item label="group:">            <el-link type="info">{{ current.group }}</el-link>          </el-form-item>          <el-form-item label="runtime:">            <el-link type="info">{{ current.runtime }}</el-link>          </el-form-item>          <el-form-item label="category:">            <el-link type="info">{{ current.category }}</el-link>          </el-form-item>        </el-form>      </template>  </test>     //==============vue3.0使用插槽//在vue3.0中,插槽使用v-slot 簡寫用#<p>	    <slot name="test" :newData="slotsData"></slot>    <slot></slot></p><HelloWorld msg="Welcome to Your Vue.js + TypeScript App">     <template #default> // 可以寫為v-slot:default  #后面跟的是插槽名稱        <p>默認插槽</p>     </template>     //作用域插槽     <template #test="{ newData }"> // 可以寫為v-slot:test="newData"       <p>{{ newData.aa }}</p>       <p>{{ newData.bb }}</p>     </template></HelloWorld>//一個組件里面具有多個插槽時,一定要帶上名稱,否則可能會導致作用域錯亂

5.自定義指令

在 Vue 2 中實現一個自定義指令:

// 注冊一個全局自定義指令 `v-focus`Vue.directive('focus', {   // 當被綁定的元素插入到 DOM 中時……   inserted: function (el) {     // 聚焦元素     el.focus()   }})

在 Vue 2 中, 自定義指令通過以下幾個可選鉤子創建:

  • bind:只調用一次,指令第一次綁定到元素時調用。在這里可以進行一次性的初始化設置。
  • inserted:被綁定元素插入父節點時調用(僅保證父節點存在,但不一定已被插入文檔中)。
  • update:所在組件的 VNode 更新時調用,但是可能發生在其子 VNode更新之前。指令的值可能發生了改變,也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新 (詳細的鉤子函數參數見下)。
  • componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調用。
  • unbind:只調用一次,指令與元素解綁時調用。

在 Vue 3 中對自定義指令的 API 進行了更加語義化的修改, 就如組件生命周期變更一樣, 都是為了更好的語義化, 變更如下:
整理分享經典技巧之vue3及與vue2的區別(部分)

所以在 Vue3 中, 可以這樣來自定義指令:

const { createApp } from "vue"const app = createApp({})app.directive('focus', {     mounted(el) {         el.focus()     }})

然后可以在模板中任何元素上使用新的 v-focus指令, 如下:

<input v-focus />

6.v-model 升級

Vue 3 中 v-model 發生了很大的變化:

變更:在自定義組件上使用v-model時, 屬性以及事件的默認名稱變了 變更:v-bind的.sync修飾符在 Vue 3 中又被去掉了, 合并到了v-model里 新增:同一組件可以同時設置多個 v-model 新增:開發者可以自定義 v-model修飾符

我們來詳細了解一下,并對比一下vue2與vue3 在組件上使用 v-model,
例如:
vue2 的輸入框的雙向綁定,其實就相當于傳遞了value屬性, 并觸發了input事件:

<!-- Vue 2 --> <input v-model="searchValue"><input>  <!-- 相當于 --> <input :value="searchValue" @input="searchValue=$event"><input>

這時v-model只能綁定在組件的value屬性上,那如果我們要給自己的組件用一個別的屬性,并且我們不想通過觸發input來更新值。

但是在實際開發中,有些場景我們可能需要對一個 prop 進行 “雙向綁定”, 這里以最常見的 dialog 為例子:dialog 挺合適屬性雙向綁定的, 外部可以控制組件的visible顯示或者隱藏,組件內部關閉可以控制 visible屬性隱藏,同時 visible 屬性同步傳輸到外部。組件內部,  當我們關閉dialog時, 在子組件中以 update:PropName 模式觸發事件。

事件為

this.$emit('update:visible', false)

然后在父組件中可以監聽這個事件進行數據更新:

<el-dialog :visible="isVisible" @update:visible="isVisible = $event"></el-dialog>

在vue2的開發中,我們實際會發現一個新的東西sync,所以也可以使用v-bind.sync來簡化實現:

<el-dialog :visible.sync="isVisible"></el-dialog>

上面說了 Vue2 中v-model實現以及組件屬性的雙向綁定,那么在 Vue 3 中應該怎樣實現的呢?
在 Vue3 中, 在自定義組件上使用v-model, 相當于傳遞一個modelValue 屬性, 同時觸發一個update:modelValue事件:

<el-dialog v-model="isVisible"></el-dialog> <!-- 相當于 --> <el-dialog :modelValue="isVisible" @update:modelValue="isVisible = $event"></el-dialog>

如果要綁定屬性名, 只需要給v-model傳遞一個參數就行, 同時可以綁定多個v-model

<el-dialog v-model:visible="isVisible" v-model:content="content"></el-dialog><!-- 相當于 --><el-dialog    :visible="isVisible"     :content="content"     @update:visible="isVisible"     @update:content="content"></el-dialog>

這個寫法完全沒有.sync什么事兒了, Vue 3 中拋棄了.sync寫法, 統一使用v-model。

7.異步組件的使用

Vue3 中 使用 defineAsyncComponent 定義異步組件,配置選項 component 替換為 loader ,Loader 函數本身不再接收 resolve 和 reject 參數,且必須返回一個 Promise,用法如下:

<template>   <!-- 異步組件的使用 -->   <AsyncPage /></tempate><script>import { defineAsyncComponent } from "vue";export default {   components: {     // 無配置項異步組件     AsyncPage: defineAsyncComponent(() => import("./NextPage.vue")),      // 有配置項異步組件     AsyncPageWithOptions: defineAsyncComponent({    loader: () => import("./NextPage.vue"),    delay: 200,    timeout: 3000,    errorComponent: () => import("./ErrorComponent.vue"),    loadingComponent: () => import("./LoadingComponent.vue"),  })   },}</script>

8.Composition API

   使用Composition API 解決我們在完成功能時,在 data、methods、computed 以及 mounted 中反復的跳轉,他將零散分布的    邏輯組合在一起維護,并可以將單獨的邏輯再分為單獨的文件

如果想要了解<script setup></script>語法糖,請移步 vue3 setup語法糖(部分總結)

我們先來了解一下Composition具有的API
整理分享經典技巧之vue3及與vue2的區別(部分)

  • setup

setup 是 Vue3.x 新增的一個選項, 他是組件內使用 Composition API的入口。

setup 執行時機
通過一段代碼 我們可以知道:

<script>import { defineComponent, reactive } from "vue";export default defineComponent({   beforeCreate() {     console.log("----beforeCreate----");   },   created() {     console.log("----created----");   },   setup() {     const state = reactive({ count: 0 });     console.log("----setup----");     return {       state,     };   },});</script>

會出現如下所示的輸出結果:
整理分享經典技巧之vue3及與vue2的區別(部分)

setup 執行時機是在 beforeCreate 之前執行,詳細的可以看后面生命周期講解。

  1. setup 參數

使用setup時,它接受兩個參數:

  • props: 組件傳入的屬性
  • context

setup 中接受的props是響應式的, 當傳入新的 props 時,會及時被更新。
由于是響應式的, 所以不可以使用 ES6 解構,解構會消除它的響應式。
錯誤代碼示例, 這段代碼會讓 props 不再支持響應式:

setup(props) {     const { name } = props;     console.log(name);     const state = reactive({ count: 0 });     return {       state,     };   },

對于以上的的問題,我們可以在后面的toRefs進行解釋。
現在我們就來講一下:

  1. reactive、ref、toRefs、readonly

在 vue2.x 中, 定義數據都是在data中。
但是 Vue3.x 可以使用reactiveref來進行數據定義。
那么ref和reactive他們有什么區別呢?

reactive用于處理對象的雙向綁定,ref處理 js 基礎類型或者處理對象的雙向綁定。 注意refs 它接受一個內部值并返回一個響應式且可變的 ref 對象。ref 對象具有指向內部值的單個 property.value。
<template>   <p>     <p>計數:{{ num }}s</p>     <p>主人年齡:{{ person.age }}</p>     <p>主人姓名:{{ person.name }}</p>     <p>動物類別:{{ animal.type }}</p>     <p>動物名稱:{{ animal.name }}</p>     <p>動物年齡:{{ animal.age }}</p>   </p></template><script>import { defineComponent, reactive, ref } from "vue";export default defineComponent({   setup() {     //使用ref聲明基本類型     const num = ref(0);     //使用ref聲明對象     const person = ref({ age: 20, name: "張三" });     //使用reactive聲明對象     const animal = reactive({ type: "貓", name: "小花", age: 5 });     setTimeout(() => {       person.value.age = person.value.age + 1;       person.value.name = "李四";       animal.age++;     }, 1000);     setInterval(() => {       num.value++;     }, 1000);     return {       num,       animal,       person,     };   },});</script>

我們綁定到頁面是通過user.name,user.age;這樣寫感覺很繁瑣,我們能不能直接將user中的屬性解構出來使用呢?
答案是不能直接對user進行結構, 這樣會消除它的響應式, 這里就和上面我們說props不能使用 ES6 直接解構就呼應上了。
那我們就想使用解構后的數據怎么辦,解決辦法就是使用toRefs
toRefs 用于將一個 reactive 對象轉化為屬性全部為 ref 對象的普通對象。具體使用方式如下:

<template>   <p>     <p>計數:{{ num }}s</p>     <p>主人年齡:{{ person.age }}</p>     <p>主人姓名:{{ person.name }}</p>     <p>動物類別:{{ atype }}</p>     <p>動物名稱:{{ aname }}</p>     <p>動物年齡:{{ aage }}</p>   </p></template><script>import { defineComponent, reactive, ref, toRefs } from "vue";export default defineComponent({   setup() {     //使用ref聲明基本類型     const num = ref(0);     //使用ref聲明對象     const person = ref({ age: 20, name: "張三" });     //使用reactive聲明對象     const animal = reactive({ atype: "貓", aname: "小花", aage: 5 });     setTimeout(() => {       person.value.age = person.value.age + 1;       person.value.name = "李四";       animal.aage++;     }, 1000);     setInterval(() => {       num.value++;     }, 1000);     return {       num,       person,       ...toRefs(animal),     };   },});</script>

有時我們想跟蹤響應式對象 (ref 或 reactive) 的變化,但我們也希望防止在應用程序的某個位置更改它,這時候,我們就需要readonly
例如,當我們有一個被傳遞的響應式對象時,我們不想讓它在傳遞的的時候被改變。為此,我們可以基于原始對象創建一個只讀的 proxy 對象:

import { reactive, readonly } from 'vue'  const original = reactive({ count: 0 })  const copy = readonly(original)  // 通過 original 修改 count,將會觸發依賴 copy 的偵聽器  original.count++  // 通過 copy 修改 count,將導致失敗并出現警告 copy.count++ // 警告: "Set operation on key 'count' failed: target is readonly."
  • 生命周期鉤子

在最開始的時候,我們就看到了兩張圖,其中的變化我們可以總結一下

整理分享經典技巧之vue3及與vue2的區別(部分)

我們可以看到beforeCreatecreatedsetup替換了(但是 Vue3 中你仍然可以使用, 因為 Vue3 是向下兼容的, 也就是你實際使用的是 vue2 的)。
其次,鉤子命名都增加了on; Vue3.x 還新增用于調試的鉤子函數onRenderTriggeredonRenderTricked
下面我們簡單使用幾個鉤子, 方便大家學習如何使用,Vue3.x 中的鉤子是需要從 vue 中導入的:

import {   defineComponent,   onBeforeMount,   onMounted,   onBeforeUpdate,   onUpdated,   onBeforeUnmount,   onUnmounted,   onErrorCaptured,   onRenderTracked,   onRenderTriggered,} from "vue";export default defineComponent({   //beforeCreate和created是vue2的   beforeCreate() {     console.log("------beforeCreate-----");   },   created() {     console.log("------created-----");   },   setup() {     console.log("------setup-----");     // vue3.x生命周期寫在setup中     onBeforeMount(() => {       console.log("------onBeforeMount-----");     });     onMounted(() => {       console.log("------onMounted-----");     });     onBeforeUpdate(() => {       console.log("------onBeforeUpdate-----");     });     onUpdated(() => {       console.log("------onUpdated-----");     });     onBeforeUnmount(() => {       console.log("------onBeforeUnmount-----");     });     onUnmounted(() => {       console.log("------onUnmounted-----");     });     onErrorCaptured(() => {       console.log("------onErrorCaptured-----");     });     onRenderTracked(() => {       console.log("------onRenderTracked-----");     });     // 調試哪些數據發生了變化     onRenderTriggered((event) => {       console.log("------onRenderTriggered-----", event);     });   },});

具體怎么使用,是干什么的請參考官方文檔,這里就不一一贅述了。

  • watch 與 watchEffect 的用法

watch 函數用來偵聽特定的數據源,并在回調函數中執行副作用。默認情況是惰性的,也就是說僅在偵聽的源數據變更時才執行回調。

watch(source, callback, [options])

參數說明:

  1. source: 可以支持 string,Object,Function,Array;
  2. 用于指定要偵聽的響應式變量 callback:
  3. 執行的回調函數 options:支持 deep、immediate 和 flush 選項。

其實整體和原來的vue2.0有一定的相似性,基本參數沒有發生大的改變。

接下來我會分別介紹這個三個參數都是如何使用的, 如果你對 watch 的使用不明白的請往下看:

//監聽reactive對象:watch(       () => animal.aage,       (curAge, preAge) => {         console.log("新值:", curAge, "老值:", preAge);       }     );//監聽ref變量  watch(num, (newVal, oldVal) => {       console.log("新值:", newVal, "老值:", oldVal);     });     //多個值的監聽  watch([() => animal.aage, num], ([curAge, newVal], [preAge, oldVal]) => {       console.log("新值:", curAge, "老值:", preAge);       console.log("新值:", newVal, "老值:", oldVal);     });     //監聽對象復雜時,請使用深度監聽 讓函數的第三個參數為deep:truewatch(       () => state.animal,       (newType, oldType) => {         console.log("新值:", newType, "老值:", oldType);       },       { deep: true }     );

默認情況下,watch 是惰性的, 那什么情況下不是惰性的, 可以立即執行回調函數呢?其實使用也很簡單, 給第三個參數中設置
immediate: true即可。

//停止監聽函數    const stopWatchRoom = watch(       () => state.animal,       (newType, oldType) => {         console.log("新值:", newType, "老值:", oldType);       },       { deep: true }     );     setTimeout(() => {       // 停止監聽       stopWatchRoom();     }, 3000);

還有一個監聽函數watchEffect,介紹一下watchEffect,看看它的使用和watch究竟有何不同,在上面代碼的基礎上,我們來編寫。

watchEffect(() => {       console.log(num);     });

執行結果首先打印一次num值;然后每隔一秒,打印num值。
從上面的代碼可以看出, 并沒有像watch一樣需要先傳入依賴,watchEffect會自動收集依賴, 只要指定一個回調函數。在組件初始化時, 會先執行一次來收集依賴, 然后當收集到的依賴中數據發生變化時, 就會再次執行回調函數。所以總結對比如下:

  • watchEffect 不需要手動傳入依賴
  • watchEffect 會先執行一次用來自動收集依賴
  • watchEffect無法獲取到變化前的值, 只能獲取變化后的值

9.Hooks

在之前vue用的mixin,所謂的混入 (mixin) 提供了一種非常靈活的方式,來分發 Vue 組件中的可復用功能。一個混入對象可以包含任意組件選項。當組件使用混入對象時,所有混入對象的選項將被“混合”進入該組件本身的選項。
現在的vue3.0提供了一種新的東西 vue-hooks。具體的vue-hooks,請參考網上教程

為什么產生了hooks
首先從class-component/vue-options說起:

  • 跨組件代碼難以復用
  • 大組件,維護困難,顆粒度不好控制,細粒度劃分時,組件嵌套存層次太深影響性能
  • 類組件,this不可控,邏輯分散,不容易理解
  • mixins具有副作用,邏輯互相嵌套,數據來源不明,且不能互相消費

當一個模版依賴了很多mixin的時候,很容易出現數據來源不清或者命名沖突的問題,而且開發mixins的時候,邏輯及邏輯依賴的屬性互相分散且mixin之間不可互相消費。這些都是開發中令人非常痛苦的點。
hooks存在以下優勢:

  • 允許hooks間相互傳遞值
  • 組件之間重用狀態邏輯
  • 明確指出邏輯來自哪里

我們先來封裝一個hooks,假如這個hooks是一個實現年齡加減,獲取雙倍年齡的函數。用單獨的文件存儲 bus/useAge.ts

import { ref, Ref, computed } from "vue";type CountResultProps = {   age: Ref<number>;   doubleAge: Ref<number>;   increase: (curAge?: number) => void;   decrease: (curAge?: number) => void;};export default function useCount(initValue = 20): CountResultProps {   const age = ref(initValue);   const increase = (curAge?: number): void => {     if (typeof curAge !== "undefined") {       age.value += curAge;     } else {       age.value += 1;     }   };   const doubleAge = computed(() => age.value * 2);   const decrease = (curAge?: number): void => {     if (typeof curAge !== "undefined") {       age.value -= curAge;     } else {       age.value -= 1;     }   };   return {     age,     doubleAge,     increase,     decrease,   };}

在組件里面調用該hooks

<template>   <p>     <p>計數:{{ num }}s</p>     <p>主人年齡:{{ person.age }}</p>     <p>主人姓名:{{ person.name }}</p>     <p>動物類別:{{ atype }}</p>     <p>動物名稱:{{ aname }}</p>     <p>動物年齡:{{ aage }}</p>     <p>count: {{ age }}</p>     <p>雙倍年齡: {{ doubleAge }}</p>     <p>       <button @click="increase()">加1</button>       <button @click="decrease()">減一</button>     </p>   </p></template><script>import {   defineComponent,   reactive,   ref,   toRefs,   watch,   watchEffect,} from "vue";import useAge from "../bus/useAge.ts";export default defineComponent({   setup() {     //使用ref聲明基本類型     const num = ref(0);     //使用ref聲明對象     const person = ref({ age: 20, name: "張三" });     //使用reactive聲明對象     const animal = reactive({ atype: "貓", aname: "小花", aage: 5 });     setTimeout(() => {       person.value.age = person.value.age + 1;       person.value.name = "李四";       animal.aage++;       animal.aname = "小橘";     }, 1000);     setInterval(() => {       num.value++;     }, 1000);     const { age, doubleAge, increase, decrease } = useAge(22);     return {       num,       person,       ...toRefs(animal),       age,       doubleAge,       increase,       decrease,     };   },});</script>

10.vue2.x 與vue3.x的響應式數據對比

在vue2.0中,應該很多人都使用了$set這個東西吧。
數據更新了,頁面為什么不變化呢?什么時候我們用$forceUpdate強制更新呢?
在vue2.x中,實現數據監聽使用的是Object.defineProperty。而vue3.x使用的是Proxy

  1. Object.defineProperty只能劫持對象的屬性, 而 Proxy 是直接代理對象

由于Object.defineProperty只能劫持對象屬性,需要遍歷對象的每一個屬性,如果屬性值也是對象,就需要遞歸進行深度遍歷。
但是Proxy 直接代理對象, 不需要遍歷操作

  1. Object.defineProperty對新增屬性需要手動進行Observe

因為Object.defineProperty劫持的是對象的屬性,所以新增屬性時,需要重新遍歷對象,
對其新增屬性再次使用Object.defineProperty進行劫持。也就是 Vue2.x
中給數組和對象新增屬性時,需要使用$set才能保證新增的屬性也是響應式的,
$set內部也是通過調用Object.defineProperty去處理的。

  1. Proxy有多種攔截方法,如apply,deleteProperty等等,是Object.defineProperty()不具備的。
  2. Proxy是返回值是一個對象,可以直接進行操作,而defineProperty()要先遍歷所有對象屬性值才能進行操作。
    但是相對來說,Object.defineProperty()兼容性高一些。

11.Teleport

Teleport 是 Vue3.x 新推出的功能

Teleport 是什么呢?

Teleport 就像是哆啦 A 夢中的「任意門」,任意門的作用就是可以將人瞬間傳送到另一個地方。有了這個認識,我們再來看一下為什么需要用到 Teleport 的特性呢,看一個小例子:

例如我們在使用Dialog組件時,我們實際開發中經常會使用到 Dialog,此時Dialog就被渲染到一層層子組件內部,處理嵌套組件的定位、z-index和樣式都變得困難。但是組件希望位于頁面的最上方,這時候我們將Dialog組件掛載在body上面是最好控制的,我們能夠很好的通過zIndex來控制Dialog的位置,當他嵌套在templat里面的時候就不那么容易了。簡單來說就是,即希望繼續在組件內部使用Dialog,又希望渲染的 DOM 結構不嵌套在組件內部的 DOM 中。

此時就需要 Teleport 上場,我們可以用<Teleport>包裹Dialog, 此時就建立了一個傳送門,可以將Dialog渲染的內容傳送到任何指定的地方。

<template>   <p>     <p>計數:{{ num }}s</p>     <p>主人年齡:{{ person.age }}</p>     <p>主人姓名:{{ person.name }}</p>     <p>動物類別:{{ atype }}</p>     <p>動物名稱:{{ aname }}</p>     <p>動物年齡:{{ aage }}</p>     <p>count: {{ age }}</p>     <p>倍數: {{ doubleAge }}</p>     <p>       <button @click="increase()">加1</button>       <button @click="decrease()">減一</button>     </p>     <el-button type="text" @click="dialogVisible = true"       >點擊打開 Dialog</el-button    >     <teleport to="#dialogLL">       <el-dialog title="提示" v-model="dialogVisible" width="30%">         <span>這是一段信息</span>         <template #footer>           <span class="dialog-footer">             <el-button @click="dialogVisible = false">取 消</el-button>             <el-button type="primary" @click="dialogVisible = false"               >確 定</el-button            >           </span>         </template>       </el-dialog>     </teleport>   </p></template><script>import {   defineComponent,   reactive,   ref,   toRefs,} from "vue";export default defineComponent({   setup() {     //使用ref聲明基本類型     const num = ref(0);     const dialogVisible = ref(false);     //使用ref聲明對象     const person = ref({ age: 20, name: "張三" });     //使用reactive聲明對象     const animal = reactive({ atype: "貓", aname: "小花", aage: 5 });     setTimeout(() => {       person.value.age = person.value.age + 1;       person.value.name = "李四";       animal.aage++;       animal.aname = "小橘";     }, 1000);     setInterval(() => {       num.value++;     }, 1000);      return {       dialogVisible,       num,       person,       ...toRefs(animal),     };   },});</script>

我們可以很清楚的看到teleport上有一個to屬性,這個屬性是講當前節點傳送到制定位置去的。位置應該傳送到哪里呢?
答案就是在index.html上面
下面是我們的首頁 你會看到有一個p的ID名為dialogLL,teleport就將節點掛載在這里來了

<!DOCTYPE html><html lang="en">   <head>     <meta charset="UTF-8" />     <link rel="icon" href="/favicon.ico" />     <meta name="viewport" content="width=device-width, initial-scale=1.0" />     <title>Vite App</title>   </head>   <body>     <p id="app"></p>     <p id="dialogLL"></p>     <script type="module" src="/src/main.js"></script>   </body></html>

如圖所示:
整理分享經典技巧之vue3及與vue2的區別(部分)

12.Suspense

Suspense是 Vue3.x 中新增的特性, 那它有什么用呢?我們通過 Vue2.x 中的一些場景來認識它的作用。 Vue2.x 中應該經常遇到這樣的場景:

<template>   <p>     <p v-if="!loading">...</p>     <p v-if="loading">加載中...</p>   </p></template>

在前后端交互獲取數據時, 是一個異步過程,一般我們都會提供一個加載中的動畫,當數據返回時配合v-if來控制數據顯示。
它提供兩個template slot, 剛開始會渲染一個 fallback 狀態下的內容, 直到到達某個條件后才會渲染 default 狀態的正式內容, 通過使用
Suspense組件進行展示異步渲染就更加的簡單。
具體的使用,我們可以用下面的例子來表示:
這是需要等待取值完成的的組件:

<template>   <h1>{{ getData.result }}</h1></template><script>export default {   name: "NewModel",   async setup() {     let getData = await new Promise((resolve) => {       setTimeout(() => {         return resolve({ result: "OK" });       }, 3000);     });     return {       getData,     };   },};</script>

在其他組件內調用它,當等待取值的組件取值完成后,會將loading狀態變為OK狀態

<template>   <p>     <suspense>       <template #default>         <NewSuspense></NewSuspense>       </template>       <template #fallback>         <h1>Loadding...</h1>       </template>     </suspense>   </p></template><script>import NewSuspense from "./suspens.vue";export default {   name: "AppMain",   components: {     NewSuspense,   },};</script><style></style>

效果如圖:
整理分享經典技巧之vue3及與vue2的區別(部分)

13.片段(Fragment)

在 Vue2.x 中, template中只允許有一個根節點:

<template>     <p>         <span></span>         <span></span>     </p></template>

但是在 Vue3.x 中,你可以直接寫多個根節點:

<template>     <span></span>     <span></span></template>

14.Tree-Shaking變化

Vue3.x 在考慮到 tree-shaking的基礎上重構了全局和內部 API, 表現結果就是現在的全局 API 需要通過 ES Module的引用方式進行具名引用, 比如在 Vue2.x 中,我們要使用 nextTick:

// vue2.ximport Vue from "vue"Vue.nextTick(()=>{     ...})或者  this.nextTick(()=>{     ...})

Vue.nextTick() 是一個從 Vue 對象直接暴露出來的全局 API,其實 $nextTick() 只是 Vue.nextTick() 的一個簡易包裝,只是為了方便而把后者的回調函數的 this 綁定到了當前的實例。
在 Vue3.x 中改寫成這樣:

import { nextTick } from "vue"nextTick(() =>{     ...})

受影響的 API

這是一個比較大的變化, 因為以前的全局 API 現在只能通過具名導入,這一更改會對以下 API 有影響:

  1. Vue.nextTick
  2. Vue.observable(用 Vue.reactive 替換)
  3. Vue.version
  4. Vue.compile(僅限完整版本時可用)
  5. Vue.set(僅在 2.x 兼容版本中可用)
  6. Vue.delete(與上同)

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
小雪好湿用力啊进来轻点| CHINESE妓女野外直播| 吃瓜视频最全观看| 久久精品国产欧美日韩| 少妇爆乳无码AV无码专区| 浴室人妻的情欲HD三级| 国产精品9999久久久久| 美区APPSTORE精品| 小蜜被两老头吸奶头| 巴西BBABBABBABBA| 久久久久亚洲精品无码网址| 婷婷综合缴情亚洲狠狠| 99无码人妻一区二区三区免费| 黑人与亚洲女人XXXXXXXⅩ| 日韩丰满少妇无码内射| 中国女人内射6XXXXXWWW| 久久精品国产精品亚洲蜜月| 欧美另类VIDEOSBESTS| 日韩精品无码一区二区中文字幕 | 一区二区三区无码免费看| 国产精品自在欧美一区| 人人妻人人妻人人人人妻妻人人人人 | 色婷婷欧美在线播放内射| √天堂中文WWW官网在线| 无码一区二区三区AV免费| 99无人区码一码二码三码四码| 九月婷婷人人澡人人添人人爽| 玩护士睡老师勾搭女下属| А√天堂8资源最新版| 门卫老头吮她的花蒂| 亚洲欧美色国产综合| 国产精品无码A∨麻豆| 日韩精品无码熟人妻视频| 99热久RE这里只有精品小草| 久久夜色精品国产亚洲AV动态图| 亚洲VA天堂VA在线VA欧美| 国产精品VA在线播放| 日韩人妻中文字幕| A级无遮挡超级高清-在线观看| 狂躁美女大BBBBBB视频U| 亚洲精品TY久久久久久久久久| 国产精品揄拍100视频| 首页 动漫 亚洲 欧美 日韩| 不卡AV一区二区| 欧美最猛黑人XXXⅩ猛男欧视频| 中文字幕AV无码免费一区| 久久久AV波多野一区二区| 亚洲国产成人精品女人久久久| 国产精品无码AV在线播放| 熟妇高潮一区二区精品| 成人免费无遮挡无码黄漫视频| 欧美人与性动交a欧美精品| 最新高清无码专区| 乱码午夜-极品国产内射| 一区无码在线观看的| 久久精品中文字幕第一页| 亚洲精华液一二三产区| 黑人与亚洲美女ⅩXXX| 亚洲AV无码片一区二区三区| 国产无遮挡又黄又爽不要VIP网| 无码一区二区av| 国产精品人成在线播放新网站 | 国产AV一区二区精品久久| 日日噜噜噜夜夜爽爽狠狠视频| 把腿张开老子cao烂你n视频| 人妻丰满熟妇AV无码区免| VODAFONEWIFI另类| 人善交VIDE欧美| 本道久久综合无码中文字幕| 日本XXXX裸体XXXX自慰| 被青梅竹马的学弟给锁定了林擎霄| 人成乱码一卡二卡三四卡五卡六卡| JAPANESE熟女熟妇| 人人妻人人爽人人添少妇| 差差差很疼30分钟的视频| 日日噜噜夜夜狠狠久久丁香五月| 大帝A∨无码视频在线播放| 少妇高潮喷水久久久影院| 国产成人亚洲精品另类动态| 无码网站天天爽免费看视频| 国产日韩AV免费无码一区二区| 亚洲av网站在线| 狠狠色噜噜狠狠狠狠色综合久AV | 免费无码AV片在线观看网站| 91夜黄性一交一乱一色一情人 | 久久精品国产久精久精| 一女大战七个黑人到喷浆| 免费人成视频X8X8入口APP| 99久久无色码中文字幕人妻| 人妻无码不卡在线视频| 丰满熟女高潮毛茸茸欧洲视频| 翁熄小莹女博士高潮连连| 国产三级精品三级在线专区1| 亚洲第一AV网站| 久久丫精品国产亚洲AV| 99国产精品无码专区| 日本VPSWINDOWS怀孕| 国产成人亚洲精品无码高潮| 亚洲AV无码精品色午夜| 久久精品露脸对白国产| .一区二区三区在线 | 欧洲| 人妻少妇精品中文字幕AV蜜桃| 芳芳好紧好滑好湿好爽| 小雪被老汉玩遍各种方式电影| 精品多毛少妇人妻AV免费久久| 伊人久久精品无码AV一区| 欧美巨大乳BBWVIDEOS| 嗯…啊 摸 湿 奶头免费视频| 性丰满ⅩXXOOO性FREE| 久久国产欧美成人网站| 99久久婷婷国产一区二区 | 娇妻系列交换27部多P小| 伊人久久精品久久亚洲一区| 欧美伊人色综合久久天天| 国产SM鞭打折磨调教视频| 亚洲国产成人久久综合三区| 久久青青草原亚洲AV无码APP| H无码动漫在线观看人| 婷婷蜜桃国产精品一区| 精品无码国产AV一区二区三区| 16—17女人毛片毛片| 色老头BGMBGMBGM| 好男人日本社区WWW| 坐公交车居然被弄了2个小时小说| 人人妻人人添人人爽日韩欧美 | 搡老女人老妇老熟女HHD| 国内揄拍国内精品人妻浪潮AV| 一区二区三区精品视频日本 | 太平公主秘史在线观看免费| 精品国产AⅤ一区天美传媒| 99RE热这里只有精品视频| 天堂中文最新版在线官网在线| 精品无码中文字幕不卡| H漫全彩纯肉无码网站| 午夜影视免费观看2023| 浪货两个都满足不了你| 大J8黑人BBW巨大怪物| 亚洲国产欧美在线人成长黄瓜| 欧美成人黑人XX视频免费观看| 国产成人综合久久亚洲精品| 伊人久久大香线焦AV综合影院| 三个男人换着躁我一个| 精品人妻一区二区三区三区换着玩| H纯肉无码精品动漫在线观看| 香蕉视频一直看一直爽| 免费女同毛片在线播放| 国产精品日本一区二区不卡视频| 在线观看免费AV网站| 天堂AV无码大芭蕉伊人AV不卡| 久久久久亚洲AV成人无码| 俄罗斯人和欧洲人的性格差异| 亚洲一卡2卡3卡4卡5卡6卡| 日本熟妇XXXX| 久久超碰97人人做人人爱| 成人欧美一区二区三区在线观看 | 岳胀耸的雪乳奶水| 天天摸日日摸狠狠添高潮喷| 鲁鲁夜夜天天综合视频| 国产丰满老熟女重口对白| 中国少妇毛多水多BXⅩ| 无码GOGO大胆啪啪艺术| 男女真人后进式猛烈动态图无打吗| 国产乱人伦AV在线麻豆A| 939W78V78W乳液永久W| 久久久99精品成人片中文字幕| 差差差无掩盖30分钟79集| 亚洲一二三四2021不卡| 熟妇女人妻丰满少妇中文字幕性生活 | 亚洲AV日韩AV高潮喷潮无码天| 欧美人与牲禽ⅩXXX伦交| 激情综合五月丁香五月激情| 成人午夜高潮刺激免费视频| 一区二区操逼视频| 无码人妻丰满熟妇奶水区码| 欧美金妇欧美乱妇XXXX| 精品国产成人亚洲午夜福利| 大肥女BBWBBWHD视频| 在线欧美精品一区二区三区 | 亚洲人妻精品一区| 天堂AV无码一区二区三区| 欧美丰满少妇人妻精品| 精品无码人妻一区二区三区不卡| 高H纯肉放荡脏话H文合集| 97免费公开在线视频| 亚洲精品无码av中文字幕电影网站| 少妇夜夜爽夜夜春夜夜高潮| 男生把自己的手到女生的QQ里 | 孩教小UXXXⅩ精品| 丰满人妻熟妇乱又伦精品APP| 18禁无遮挡羞羞啪啪免费网站| 亚洲国产精品无码久久青草| 少妇被躁爽到高潮无码文| 欧美96在线 | 欧| 久久精品国产亚洲AV麻豆软件| 国产精品亚洲А∨天堂2018| 被黑人上司侵犯狂草内射| 中文字幕一区二区精品区| 亚洲人成色A777777在线观| 五月丁香综合缴情六月小说| 日韩A人毛片精品无人区乱码 |