久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      全面詳細總結Vue3.0的新特性(總結分享)

      本篇文章給大家?guī)韛ue3.0新特性的總結分享,Vue3.0從20年九月發(fā)布第一個One Piece版本,到現(xiàn)在一直在更新優(yōu)化;中文版的官方文檔也已經放出;那么作為終端用戶的我們來看下Vue3新增了哪些功能和特性。希望對大家有幫助。

      全面詳細總結Vue3.0的新特性(總結分享)

      尤大大在B站直播時分享了Vue3.0的幾個亮點:

      • Performance:性能優(yōu)化

      • Tree-shaking support:支持搖樹優(yōu)化

      • Composition API:組合API

      • Fragment,Teleport,Suspense:新增的組件

      • Better TypeScript support:更好的TypeScript支持

      • Custom Renderer API:自定義渲染器

      在性能方面,對比Vue2.x,性能提升了1.3~2倍左右;打包后的體積也更小了,如果單單寫一個HelloWorld進行打包,只有13.5kb;加上所有運行時特性,也不過22.5kb。

      那么作為終端用戶的我們,在開發(fā)時,和Vue2.x有什么不同呢?Talk is cheap,我們還是來看代碼。

      Tree-shaking

      Vue3最重要的變化之一就是引入了Tree-Shaking,Tree-Shaking帶來的bundle體積更小是顯而易見的。在2.x版本中,很多函數(shù)都掛載在全局Vue對象上,比如nextTick、nextTick、nextTick、set等函數(shù),因此雖然我們可能用不到,但打包時只要引入了vue這些全局函數(shù)仍然會打包進bundle中。

      而在Vue3中,所有的API都通過ES6模塊化的方式引入,這樣就能讓webpack或rollup等打包工具在打包時對沒有用到API進行剔除,最小化bundle體積;我們在main.js中就能發(fā)現(xiàn)這樣的變化:

      //src/main.js import { createApp } from "vue"; import App from "./App.vue"; import router from "./router";  const app = createApp(App); app.use(router).mount("#app");

      創(chuàng)建app實例方式從原來的new Vue()變?yōu)橥ㄟ^createApp函數(shù)進行創(chuàng)建;不過一些核心的功能比如virtualDOM更新算法和響應式系統(tǒng)無論如何都是會被打包的;這樣帶來的變化就是以前在全局配置的組件(Vue.component)、指令(Vue.directive)、混入(Vue.mixin)和插件(Vue.use)等變?yōu)橹苯訏燧d在實例上的方法;我們通過創(chuàng)建的實例來調用,帶來的好處就是一個應用可以有多個Vue實例,不同實例之間的配置也不會相互影響:

      const app = createApp(App) app.use(/* ... */) app.mixin(/* ... */) app.component(/* ... */) app.directive(/* ... */)

      因此Vue2.x的以下全局API也需要改為ES6模塊化引入:

      • Vue.nextTick

      • Vue.observable不再支持,改為reactive

      • Vue.version

      • Vue.compile (僅全構建)

      • Vue.set (僅兼容構建)

      • Vue.delete (僅兼容構建)

      除此之外,vuex和vue-router也都使用了Tree-Shaking進行了改進,不過api的語法改動不大:

      //src/store/index.js import { createStore } from "vuex";  export default createStore({   state: {},   mutations: {},   actions: {},   modules: {}, }); //src/router/index.js import { createRouter, createWebHistory } from "vue-router";  const router = createRouter({   history: createWebHistory(process.env.BASE_URL),   routes, });

      生命周期函數(shù)

      我們都知道,在Vue2.x中有8個生命周期函數(shù):

      • beforeCreate

      • created

      • beforeMount

      • mounted

      • beforeUpdate

      • updated

      • beforeDestroy

      • destroyed

      在vue3中,新增了一個setup生命周期函數(shù),setup執(zhí)行的時機是在beforeCreate生命函數(shù)之前執(zhí)行,因此在這個函數(shù)中是不能通過this來獲取實例的;同時為了命名的統(tǒng)一,將beforeDestroy改名為beforeUnmountdestroyed改名為unmounted,因此vue3有以下生命周期函數(shù):

      • beforeCreate(建議使用setup代替)

      • created(建議使用setup代替)

      • setup

      • beforeMount

      • mounted

      • beforeUpdate

      • updated

      • beforeUnmount

      • unmounted

      同時,vue3新增了生命周期鉤子,我們可以通過在生命周期函數(shù)前加on來訪問組件的生命周期,我們可以使用以下生命周期鉤子:

      • onBeforeMount

      • onMounted

      • onBeforeUpdate

      • onUpdated

      • onBeforeUnmount

      • onUnmounted

      • onErrorCaptured

      • onRenderTracked

      • onRenderTriggered

      那么這些鉤子函數(shù)如何來進行調用呢?我們在setup中掛載生命周期鉤子,當執(zhí)行到對應的生命周期時,就調用對應的鉤子函數(shù):

      import { onBeforeMount, onMounted } from "vue"; export default {   setup() {     console.log("----setup----");     onBeforeMount(() => {       // beforeMount代碼執(zhí)行     });     onMounted(() => {       // mounted代碼執(zhí)行     });   }, }

      新增的功能

      說完生命周期,下面就是我們期待的Vue3新增加的那些功能。

      響應式API

      我們可以使用reactive來為JS對象創(chuàng)建響應式狀態(tài):

      import { reactive, toRefs } from "vue"; const user = reactive({   name: 'Vue2',   age: 18, }); user.name = 'Vue3'

      reactive相當于Vue2.x中的Vue.observable。

      reactive函數(shù)只接收object和array等復雜數(shù)據(jù)類型。

      對于一些基本數(shù)據(jù)類型,比如字符串和數(shù)值等,我們想要讓它變成響應式,我們當然也可以通過reactive函數(shù)創(chuàng)建對象的方式,但是Vue3提供了另一個函數(shù)ref

      import { ref } from "vue"; const num = ref(0); const str = ref(""); const male = ref(true);  num.value++; console.log(num.value);  str.value = "new val"; console.log(str.value);  male.value = false; console.log(male.value);

      ref返回的響應式對象是只包含一個名為value參數(shù)的RefImpl對象,在js中獲取和修改都是通過它的value屬性;但是在模板中被渲染時,自動展開內部的值,因此不需要在模板中追加.value。

      <template>   <p>     <span>{{ count }}</span>     <button @click="count ++">Increment count</button>   </p> </template>  <script>   import { ref } from 'vue'   export default {     setup() {       const count = ref(0)       return {         count       }     }   } </script>

      reactive主要負責復雜數(shù)據(jù)結構,而ref主要處理基本數(shù)據(jù)結構;但是很多童鞋就會誤解ref只能處理基本數(shù)據(jù),ref本身也是能處理對象和數(shù)組的:

      import { ref } from "vue";  const obj = ref({   name: "qwe",   age: 1, }); setTimeout(() => {   obj.value.name = "asd"; }, 1000);  const list = ref([1, 2, 3, 4, 6]); setTimeout(() => {   list.value.push(7); }, 2000);

      當我們處理一些大型響應式對象的property時,我們很希望使用ES6的解構來獲取我們想要的值:

      let book = reactive({   name: 'Learn Vue',   year: 2020,   title: 'Chapter one' }) let {   name, } = book  name = 'new Learn' // Learn Vue console.log(book.name);

      但是很遺憾,這樣會消除它的響應式;對于這種情況,我們可以將響應式對象轉換為一組ref,這些ref將保留與源對象的響應式關聯(lián):

      let book = reactive({   name: 'Learn Vue',   year: 2020,   title: 'Chapter one' }) let {   name, } = toRefs(book)  // 注意這里解構出來的name是ref對象 // 需要通過value來取值賦值 name.value = 'new Learn' // new Learn console.log(book.name);

      對于一些只讀數(shù)據(jù),我們希望防止它發(fā)生任何改變,可以通過readonly來創(chuàng)建一個只讀的對象:

      import { reactive, readonly } from "vue"; let book = reactive({   name: 'Learn Vue',   year: 2020,   title: 'Chapter one' })  const copy = readonly(book); //Set operation on key "name" failed: target is readonly. copy.name = "new copy";

      有時我們需要的值依賴于其他值的狀態(tài),在vue2.x中我們使用computed函數(shù)來進行計算屬性,在vue3中將computed功能進行了抽離,它接受一個getter函數(shù),并為getter返回的值創(chuàng)建了一個不可變的響應式ref對象:

      const num = ref(0); const double = computed(() => num.value * 2); num.value++; // 2 console.log(double.value); // Warning: computed value is readonly double.value = 4

      或者我們也可以使用get和set函數(shù)創(chuàng)建一個可讀寫的ref對象:

      const num = ref(0); const double = computed({   get: () => num.value * 2,   set: (val) => (num.value = val / 2), });  num.value++; // 2 console.log(double.value);  double.value = 8 // 4 console.log(num.value);

      響應式偵聽

      和computed相對應的就是watch,computed是多對一的關系,而watch則是一對多的關系;vue3也提供了兩個函數(shù)來偵聽數(shù)據(jù)源的變化:watch和watchEffect。

      我們先來看下watch,它的用法和組件的watch選項用法完全相同,它需要監(jiān)聽某個數(shù)據(jù)源,然后執(zhí)行具體的回調函數(shù),我們首先看下它監(jiān)聽單個數(shù)據(jù)源的用法:

      import { reactive, ref, watch } from "vue";  const state = reactive({   count: 0, });  //偵聽時返回值得getter函數(shù) watch(   () => state.count,   (count, prevCount) => {     // 1 0     console.log(count, prevCount);   } ); state.count++;  const count = ref(0); //直接偵聽ref watch(count, (count, prevCount) => {   // 2 0   console.log(count, prevCount, "watch"); }); count.value = 2;

      我們也可以把多個值放在一個數(shù)組中進行偵聽,最后的值也以數(shù)組形式返回:

      const state = reactive({   count: 1, }); const count = ref(2); watch([() => state.count, count], (newVal, oldVal) => {   //[3, 2]  [1, 2]   //[3, 4]  [3, 2]   console.log(newVal, oldVal); }); state.count = 3;  count.value = 4;

      如果我們來偵聽一個深度嵌套的對象屬性變化時,需要設置deep:true

      const deepObj = reactive({   a: {     b: {       c: "hello",     },   }, });  watch(   () => deepObj,   (val, old) => {     // new hello new hello     console.log(val.a.b.c, old.a.b.c);   },   { deep: true } );  deepObj.a.b.c = "new hello";

      最后的打印結果可以發(fā)現(xiàn)都是改變后的值,這是因為偵聽一個響應式對象始終返回該對象的引用,因此我們需要對值進行深拷貝:

      import _ from "lodash"; const deepObj = reactive({   a: {     b: {       c: "hello",     },   }, });  watch(   () => _.cloneDeep(deepObj),   (val, old) => {     // new hello hello     console.log(val.a.b.c, old.a.b.c);   },   { deep: true } );  deepObj.a.b.c = "new hello";

      一般偵聽都會在組件銷毀時自動停止,但是有時候我們想在組件銷毀前手動的方式進行停止,可以調用watch返回的stop函數(shù)進行停止:

      const count = ref(0);  const stop = watch(count, (count, prevCount) => {   // 不執(zhí)行   console.log(count, prevCount); });  setTimeout(()=>{   count.value = 2; }, 1000); // 停止watch stop();

      還有一個函數(shù)watchEffect也可以用來進行偵聽,但是都已經有watch了,這個watchEffect和watch有什么區(qū)別呢?他們的用法主要有以下幾點不同:

      1. watchEffect不需要手動傳入依賴
      2. 每次初始化時watchEffect都會執(zhí)行一次回調函數(shù)來自動獲取依賴
      3. watchEffect無法獲取到原值,只能得到變化后的值
      import { reactive, ref, watch, watchEffect } from "vue";  const count = ref(0); const state = reactive({   year: 2021, });  watchEffect(() => {   console.log(count.value);   console.log(state.year); }); setInterval(() => {   count.value++;   state.year++; }, 1000);

      watchEffect會在頁面加載時自動執(zhí)行一次,追蹤響應式依賴;在加載后定時器每隔1s執(zhí)行時,watchEffect都會監(jiān)聽到數(shù)據(jù)的變化自動執(zhí)行,每次執(zhí)行都是獲取到變化后的值。

      組合API

      Composition API(組合API)也是Vue3中最重要的一個功能了,之前的2.x版本采用的是Options API(選項API),即官方定義好了寫法:data、computed、methods,需要在哪里寫就在哪里寫,這樣帶來的問題就是隨著功能增加,代碼也越來復雜,我們看代碼需要上下反復橫跳:

      全面詳細總結Vue3.0的新特性(總結分享)

      Composition API對比

      上圖中,一種顏色代表一個功能,我們可以看到Options API的功能代碼比較分散;Composition API則可以將同一個功能的邏輯,組織在一個函數(shù)內部,利于維護。

      我們首先來看下之前Options API的寫法:

      export default {   components: {},   data() {},   computed: {},   watch: {},   mounted() {}, }

      Options API就是將同一類型的東西放在同一個選項中,當我們的數(shù)據(jù)比較少的時候,這樣的組織方式是比較清晰的;但是隨著數(shù)據(jù)增多,我們維護的功能點會涉及到多個data和methods,但是我們無法感知哪些data和methods是需要涉及到的,經常需要來回切換查找,甚至是需要理解其他功能的邏輯,這也導致了組件難以理解和閱讀。

      Composition API做的就是把同一功能的代碼放到一起維護,這樣我們需要維護一個功能點的時候,不用去關心其他的邏輯,只關注當前的功能;Composition API通過setup選項來組織代碼:

      export default {   setup(props, context) {} };

      我們看到這里它接收了兩個參數(shù)props和context,props就是父組件傳入的一些數(shù)據(jù),context是一個上下文對象,是從2.x暴露出來的一些屬性:

      • attrs

      • slots

      • emit

      注:props的數(shù)據(jù)也需要通過toRefs解構,否則響應式數(shù)據(jù)會失效。

      我們通過一個Button按鈕來看下setup具體的用法:

      全面詳細總結Vue3.0的新特性(總結分享)

      舉個栗子

      <template>   <p>{{ state.count }} * 2 = {{ double }}</p>   <p>{{ num }}</p>   <p @click="add">Add</p> </template> <script> import { reactive, computed, ref } from "vue"; export default {   name: "Button",   setup() {     const state = reactive({       count: 1,     });     const num = ref(2);     function add() {       state.count++;       num.value += 10;     }     const double = computed(() => state.count * 2);     return {       state,       double,       num,       add,     };   }, }; </script>

      很多童鞋可能就有疑惑了,這跟我在data和methods中寫沒什么區(qū)別么,不就是把他們放到一起么?我們可以將setup中的功能進行提取分割成一個一個獨立函數(shù),每個函數(shù)還可以在不同的組件中進行邏輯復用:

      export default {   setup() {     const { networkState } = useNetworkState();     const { user } = userDeatil();     const { list } = tableData();     return {       networkState,       user,       list,     };   }, }; function useNetworkState() {} function userDeatil() {} function tableData() {}

      Fragment

      所謂的Fragment,就是片段;在vue2.x中,要求每個模板必須有一個根節(jié)點,所以我們代碼要這樣寫:

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

      或者在Vue2.x中還可以引入vue-fragments庫,用一個虛擬的fragment代替p;在React中,解決方法是通過的一個React.Fragment標簽創(chuàng)建一個虛擬元素;在Vue3中我們可以直接不需要根節(jié)點:

      <template>     <span>hello</span>     <span>world</span> </template>

      這樣就少了很多沒有意義的p元素。

      Teleport

      Teleport翻譯過來就是傳送、遠距離傳送的意思;顧名思義,它可以將插槽中的元素或者組件傳送到頁面的其他位置:

      全面詳細總結Vue3.0的新特性(總結分享)

      傳送門游戲

      在React中可以通過createPortal函數(shù)來創(chuàng)建需要傳送的節(jié)點;本來尤大大想起名叫Portal,但是H5原生的Portal標簽也在計劃中,雖然有一些安全問題,但是為了避免重名,因此改成Teleport。

      Teleport一個常見的使用場景,就是在一些嵌套比較深的組件來轉移模態(tài)框的位置。雖然在邏輯上模態(tài)框是屬于該組件的,但是在樣式和DOM結構上,嵌套層級后較深后不利于進行維護(z-index等問題);因此我們需要將其進行剝離出來:

      <template>   <button @click="showDialog = true">打開模態(tài)框</button>    <teleport to="body">     <p class="modal" v-if="showDialog" style="position: fixed">       我是一個模態(tài)框       <button @click="showDialog = false">關閉</button>       <child-component :msg="msg"></child-component>     </p>   </teleport> </template> <script> export default {   data() {     return {       showDialog: false,       msg: "hello"     };   }, }; </script>

      這里的Teleport中的modal p就被傳送到了body的底部;雖然在不同的地方進行渲染,但是Teleport中的元素和組件還是屬于父組件的邏輯子組件,還是可以和父組件進行數(shù)據(jù)通信。Teleport接收兩個參數(shù)todisabled

      • to – string:必須是有效的查詢選擇器或 HTMLElement,可以id或者class選擇器等。

      • disabled – boolean:如果是true表示禁用teleport的功能,其插槽內容將不會移動到任何位置,默認false不禁用。

      Suspense

      Suspense是Vue3推出的一個內置組件,它允許我們的程序在等待異步組件時渲染一些后備的內容,可以讓我們創(chuàng)建一個平滑的用戶體驗;Vue中加載異步組件其實在Vue2.x中已經有了,我們用的vue-router中加載的路由組件其實也是一個異步組件:

      export default {   name: "Home",   components: {     AsyncButton: () => import("../components/AsyncButton"),   }, }

      在Vue3中重新定義,異步組件需要通過defineAsyncComponent來進行顯示的定義:

      // 全局定義異步組件 //src/main.js import { defineAsyncComponent } from "vue"; const AsyncButton = defineAsyncComponent(() =>   import("./components/AsyncButton.vue") ); app.component("AsyncButton", AsyncButton);   // 組件內定義異步組件 // src/views/Home.vue import { defineAsyncComponent } from "vue"; export default {   components: {     AsyncButton: defineAsyncComponent(() =>       import("../components/AsyncButton")     ),   }, };

      同時對異步組件的可以進行更精細的管理:

      export default {   components: {     AsyncButton: defineAsyncComponent({       delay: 100,       timeout: 3000,       loader: () => import("../components/AsyncButton"),       errorComponent: ErrorComponent,       onError(error, retry, fail, attempts) {         if (attempts <= 3) {           retry();         } else {           fail();         }       },     }),   }, };

      這樣我們對異步組件加載情況就能掌控,在加載失敗也能重新加載或者展示異常的狀態(tài):

      全面詳細總結Vue3.0的新特性(總結分享)

      異步組件加載失敗

      我們回到Suspense,上面說到它主要是在組件加載時渲染一些后備的內容,它提供了兩個slot插槽,一個default默認,一個fallback加載中的狀態(tài):

      <template>   <p>     <button @click="showButton">展示異步組件</button>     <template v-if="isShowButton">       <Suspense>         <template #default>           <AsyncButton></AsyncButton>         </template>         <template #fallback>           <p>組件加載中...</p>         </template>       </Suspense>     </template>   </p> </template> <script> export default {   setup() {     const isShowButton = ref(false);     function showButton() {       isShowButton.value = true;     }     return {       isShowButton,       showButton,     };   }, } </script>

      全面詳細總結Vue3.0的新特性(總結分享)

      異步組件加載顯示占位

      非兼容的功能

      非兼容的功能主要是一些和Vue2.x版本改動較大的語法,已經在Vue3上可能存在兼容問題了。

      data、mixin和filter

      在Vue2.x中,我們可以定義data為object或者function,但是我們知道在組件中如果data是object的話會出現(xiàn)數(shù)據(jù)互相影響,因為object是引用數(shù)據(jù)類型;

      在Vue3中,data只接受function類型,通過function返回對象;同時Mixin的合并行為也發(fā)生了改變,當mixin和基類中data合并時,會執(zhí)行淺拷貝合并:

      const Mixin = {   data() {     return {       user: {         name: 'Jack',         id: 1,         address: {           prov: 2,           city: 3,         },       }     }   } } const Component = {   mixins: [Mixin],   data() {     return {       user: {         id: 2,         address: {           prov: 4,         },       }     }   } }  // vue2結果: {   id: 2,   name: 'Jack',   address: {     prov: 4,     city: 3   } }  // vue3結果: user: {   id: 2,   address: {     prov: 4,   }, }

      我們看到最后合并的結果,vue2.x會進行深拷貝,對data中的數(shù)據(jù)向下深入合并拷貝;而vue3只進行淺層拷貝,對data中數(shù)據(jù)發(fā)現(xiàn)已存在就不合并拷貝。

      在vue2.x中,我們還可以通過過濾器filter來處理一些文本內容的展示:

      <template>   <p>{{ status | statusText }}</p> </template> <script>   export default {     props: {       status: {         type: Number,         default: 1       }     },     filters: {       statusText(value){         if(value === 1){           return '訂單未下單'         } else if(value === 2){           return '訂單待支付'         } else if(value === 3){           return '訂單已完成'         }       }     }   } </script>

      最常見的就是處理一些訂單的文案展示等;然而在vue3中,過濾器filter已經刪除,不再支持了,官方建議使用方法調用或者計算屬性computed來進行代替。

      v-model

      在Vue2.x中,v-model相當于綁定value屬性和input事件,它本質也是一個語法糖:

      <child-component v-model="msg"></child-component> <!-- 相當于 --> <child-component :value="msg" @input="msg=$event"></child-component>

      在某些情況下我們需要對多個值進行雙向綁定,其他的值就需要顯示的使用回調函數(shù)來改變了:

      <child-component      v-model="msg"      :msg1="msg1"      @change1="msg1=$event"     :msg2="msg2"      @change2="msg2=$event"> </child-component>

      在vue2.3.0+版本引入了.sync修飾符,其本質也是語法糖,是在組件上綁定@update:propName回調,語法更簡潔:

      <child-component      :msg1.sync="msg1"      :msg2.sync="msg2"> </child-component>  <!-- 相當于 -->  <child-component      :msg1="msg1"      @update:msg1="msg1=$event"     :msg2="msg2"     @update:msg2="msg2=$event"> </child-component>

      Vue3中將v-model.sync進行了功能的整合,拋棄了.sync,表示:多個雙向綁定value值直接用多個v-model傳就好了;同時也將v-model默認傳的prop名稱由value改成了modelValue:

      <child-component      v-model="msg"> </child-component>  <!-- 相當于 --> <child-component    :modelValue="msg"   @update:modelValue="msg = $event"> </child-component>

      如果我們想通過v-model傳遞多個值,可以將一個argument傳遞給v-model:

      <child-component      v-model.msg1="msg1"     v-model.msg2="msg2"> </child-component>  <!-- 相當于 --> <child-component      :msg1="msg1"      @update:msg1="msg1=$event"     :msg2="msg2"     @update:msg2="msg2=$event"> </child-component>

      v-for和key

      在Vue2.x中,我們都知道v-for每次循環(huán)都需要給每個子節(jié)點一個唯一的key,還不能綁定在template標簽上,

      <template v-for="item in list">   <p :key="item.id">...</p>   <span :key="item.id">...</span> </template>

      而在Vue3中,key值應該被放置在template標簽上,這樣我們就不用為每個子節(jié)點設一遍:

      <template v-for="item in list" :key="item.id">   <p>...</p>   <span>...</span> </template>

      v-bind合并

      在vue2.x中,如果一個元素同時定義了v-bind="object"和一個相同的單獨的屬性,那么這個單獨的屬性會覆蓋object中的綁定:

      <p id="red" v-bind="{ id: 'blue' }"></p> <p v-bind="{ id: 'blue' }" id="red"></p>  <!-- 最后結果都相同 --> <p id="red"></p>

      然而在vue3中,如果一個元素同時定義了v-bind="object"和一個相同的單獨的屬性,那么聲明綁定的順序決定了最后的結果(后者覆蓋前者):

      <!-- template --> <p id="red" v-bind="{ id: 'blue' }"></p> <!-- result --> <p id="blue"></p>  <!-- template --> <p v-bind="{ id: 'blue' }" id="red"></p> <!-- result --> <p id="red"></p>

      v-for中ref

      vue2.x中,在v-for上使用ref屬性,通過this.$refs會得到一個數(shù)組:

      <template   <p v-for="item in list" :ref="setItemRef"></p> </template> <script> export default {   data(){     list: [1, 2]   },   mounted () {     // [p, p]     console.log(this.$refs.setItemRef)    } } </script>

      但是這樣可能不是我們想要的結果;因此vue3不再自動創(chuàng)建數(shù)組,而是將ref的處理方式變?yōu)榱撕瘮?shù),該函數(shù)默認傳入該節(jié)點:

      <template   <p v-for="item in 3" :ref="setItemRef"></p> </template> <script> import { reactive, onUpdated } from 'vue' export default {   setup() {     let itemRefs = reactive([])      const setItemRef = el => {       itemRefs.push(el)     }      onUpdated(() => {       console.log(itemRefs)     })      return {       itemRefs,       setItemRef     }   } } </script>

      v-for和v-if優(yōu)先級

      在vue2.x中,在一個元素上同時使用v-for和v-if,v-for有更高的優(yōu)先級,因此在vue2.x中做性能優(yōu)化,有一個重要的點就是v-for和v-if不能放在同一個元素上。

      而在vue3中,v-ifv-for有更高的優(yōu)先級。因此下面的代碼,在vue2.x中能正常運行,但是在vue3中v-if生效時并沒有item變量,因此會報錯:

      <template>   <p v-for="item in list" v-if="item % 2 === 0" :key="item">{{ item }}</p> </template>  <script> export default {   data() {     return {       list: [1, 2, 3, 4, 5],     };   }, }; </script>

      總結

      贊(1)
      分享到: 更多 (0)
      ?
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號