<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專(zhuān)題視頻專(zhuān)題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專(zhuān)題1關(guān)鍵字專(zhuān)題50關(guān)鍵字專(zhuān)題500關(guān)鍵字專(zhuān)題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專(zhuān)題關(guān)鍵字專(zhuān)題tag2tag3文章專(zhuān)題文章專(zhuān)題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專(zhuān)題3
        問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
        當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

        Vue 3.0 前瞻Vue Function API新特性體驗(yàn)

        來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 21:52:34
        文檔

        Vue 3.0 前瞻Vue Function API新特性體驗(yàn)

        Vue 3.0 前瞻Vue Function API新特性體驗(yàn):最近 Vue 官方公布了 Vue 3.0 最重要的RFC:Function-based component API,并發(fā)布了兼容 Vue 2.0 版本的 plugin:vue-function-api,可用于提前體驗(yàn) Vue 3.0 版本的 Function-based component API。筆者出于學(xué)習(xí)的目的,提前在
        推薦度:
        導(dǎo)讀Vue 3.0 前瞻Vue Function API新特性體驗(yàn):最近 Vue 官方公布了 Vue 3.0 最重要的RFC:Function-based component API,并發(fā)布了兼容 Vue 2.0 版本的 plugin:vue-function-api,可用于提前體驗(yàn) Vue 3.0 版本的 Function-based component API。筆者出于學(xué)習(xí)的目的,提前在

        最近 Vue 官方公布了 Vue 3.0 最重要的RFC:Function-based component API,并發(fā)布了兼容 Vue 2.0 版本的 plugin:vue-function-api,可用于提前體驗(yàn) Vue 3.0 版本的 Function-based component API。筆者出于學(xué)習(xí)的目的,提前在項(xiàng)目中嘗試了vue-function-api。

        筆者計(jì)劃寫(xiě)兩篇文章,本文為筆者計(jì)劃的第一篇,主要為筆者在體驗(yàn) Vue Function API 的學(xué)習(xí)心得。第二篇計(jì)劃寫(xiě)閱讀vue-function-api的核心部分代碼原理,包括setup、observable、lifecycle。

        本文閱讀時(shí)間約為15~20分鐘。

        概述

        Vue 2.x 及以前的高階組件的組織形式或多或少都會(huì)面臨一些問(wèn)題,特別是在需要處理重復(fù)邏輯的項(xiàng)目中,一旦開(kāi)發(fā)者組織項(xiàng)目結(jié)構(gòu)組織得不好,組件代碼極有可能被人詬病為“膠水代碼”。而在 Vue 2.x 及之前的版本,解決此類(lèi)問(wèn)題的辦法大致是下面的方案:

      1. mixin
      2. 函數(shù)式組件
      3. slots
      4. 筆者維護(hù)的項(xiàng)目也需要處理大量復(fù)用邏輯,在這之前,筆者一直嘗試使用mixin的方式來(lái)實(shí)現(xiàn)組件的復(fù)用。有些問(wèn)題也一直會(huì)對(duì)開(kāi)發(fā)者和維護(hù)者造成困惑,如一個(gè)組件同時(shí)mixin多個(gè)組件,很難分清對(duì)應(yīng)的屬性或方法寫(xiě)在哪個(gè)mixin里。其次,mixin的命名空間沖突也可能造成問(wèn)題。難以保證不同的mixin不用到同一個(gè)屬性名。為此,官方團(tuán)隊(duì)提出函數(shù)式寫(xiě)法的意見(jiàn)征求稿,也就是RFC:Function-based component API。使用函數(shù)式的寫(xiě)法,可以做到更靈活地復(fù)用組件,開(kāi)發(fā)者在組織高階組件時(shí),不必在組件組織上考慮復(fù)用,可以更好地把精力集中在功能本身的開(kāi)發(fā)上。

        注:本文只是筆者使用vue-function-api提前體驗(yàn) Vue Function API ,而這個(gè) API 只是 Vue 3.0 的 RFC,而并非與最終 Vue 3.x API 一致。發(fā)布后可能有不一致的地方。

        在 Vue 2.x 中使用

        要想提前在Vue 2.x中體驗(yàn) Vue Function API ,需要引入vue-function-api,基本引入方式如下:

        import Vue from 'vue';
        import { plugin as VueFunctionApiPlugin } from 'vue-function-api';
        
        Vue.use(VueFunctionApiPlugin);
        
        

        基本組件示例

        先來(lái)看一個(gè)基本的例子:

        <template>
         <div>
         <span>count is {{ count }}</span>
         <span>plusOne is {{ plusOne }}</span>
         <button @click="increment">count++</button>
         </div>
        </template>
        
        <script>
        import Vue from 'vue';
        import { value, computed, watch, onMounted } from 'vue-function-api';
        
        export default {
         setup(props, context) {
         // reactive state
         const count = value(0);
         // computed state
         const plusOne = computed(() => count.value + 1);
         // method
         const increment = () => {
         count.value++;
         };
         // watch
         watch(
         () => count.value * 2,
         val => {
         console.log(`count * 2 is ${val}`);
         }
         );
         // lifecycle
         onMounted(() => {
         console.log(`mounted`);
         });
         // expose bindings on render context
         return {
         count,
         plusOne,
         increment,
         };
         },
        };
        </script>
        
        

        詳解

        setup

        setup函數(shù)是Vue Function API 構(gòu)建的函數(shù)式寫(xiě)法的主邏輯,當(dāng)組件被創(chuàng)建時(shí),就會(huì)被調(diào)用,函數(shù)接受兩個(gè)參數(shù),分別是父級(jí)組件傳入的props和當(dāng)前組件的上下文context。看下面這個(gè)例子,可以知道在context中可以獲取到下列屬性值:

        const MyComponent = {
         props: {
         name: String
         },
         setup(props, context) {
         console.log(props.name);
         // context.attrs
         // context.slots
         // context.refs
         // context.emit
         // context.parent
         // context.root
         }
        }
        

        value & state

        value函數(shù)創(chuàng)建一個(gè)包裝對(duì)象,它包含一個(gè)響應(yīng)式屬性value:

        那么為何要使用value呢,因?yàn)樵贘avaScript中,基本類(lèi)型并沒(méi)有引用,為了保證屬性是響應(yīng)式的,只能借助包裝對(duì)象來(lái)實(shí)現(xiàn),這樣做的好處是組件狀態(tài)會(huì)以引用的方式保存下來(lái),從而可以被在setup中調(diào)用的不同的模塊的函數(shù)以參數(shù)的形式傳遞,既能復(fù)用邏輯,又能方便地實(shí)現(xiàn)響應(yīng)式。

        直接獲取包裝對(duì)象的值必須使用.value,但是,如果包裝對(duì)象作為另一個(gè)響應(yīng)式對(duì)象的屬性,Vue內(nèi)部會(huì)通過(guò)proxy來(lái)自動(dòng)展開(kāi)包裝對(duì)象。同時(shí),在模板渲染的上下文中,也會(huì)被自動(dòng)展開(kāi)。

        import { state, value } from 'vue-function-api';
        const MyComponent = {
         setup() {
         const count = value(0);
         const obj = state({
         count,
         });
         console.log(obj.count) // 作為另一個(gè)響應(yīng)式對(duì)象的屬性,會(huì)被自動(dòng)展開(kāi)
        
         obj.count++ // 作為另一個(gè)響應(yīng)式對(duì)象的屬性,會(huì)被自動(dòng)展開(kāi)
         count.value++ // 直接獲取響應(yīng)式對(duì)象,必須使用.value
        
         return {
         count,
         };
         },
         template: `<button @click="count++">{{ count }}</button>`,
        };
        
        

        如果某一個(gè)狀態(tài)不需要在不同函數(shù)中被響應(yīng)式修改,可以通過(guò)state創(chuàng)建響應(yīng)式對(duì)象,這個(gè)state創(chuàng)建的響應(yīng)式對(duì)象并不是包裝對(duì)象,不需要使用.value來(lái)取值。

        watch & computed

        watch和computed的基本概念與 Vue 2.x 的watch和computed一致,watch可以用于追蹤狀態(tài)變化來(lái)執(zhí)行一些后續(xù)操作,computed用于計(jì)算屬性,用于依賴屬性發(fā)生變化進(jìn)行重新計(jì)算。

        computed返回一個(gè)只讀的包裝對(duì)象,和普通包裝對(duì)象一樣可以被setup函數(shù)返回,這樣就可以在模板上下文中使用computed屬性。可以接受兩個(gè)參數(shù),第一個(gè)參數(shù)返回當(dāng)前的計(jì)算屬性值,當(dāng)傳遞第二個(gè)參數(shù)時(shí),computed是可寫(xiě)的。

        import { value, computed } from 'vue-function-api';
        
        const count = value(0);
        const countPlusOne = computed(() => count.value + 1);
        
        console.log(countPlusOne.value); // 1
        
        count.value++;
        console.log(countPlusOne.value); // 2
        
        // 可寫(xiě)的計(jì)算屬性值
        const writableComputed = computed(
         // read
         () => count.value + 1,
         // write
         val => {
         count.value = val - 1;
         },
        );
        
        

        watch第一個(gè)參數(shù)和computed類(lèi)似,返回被監(jiān)聽(tīng)的包裝對(duì)象屬性值,不過(guò)另外需要傳遞兩個(gè)參數(shù):第二個(gè)參數(shù)是回調(diào)函數(shù),當(dāng)數(shù)據(jù)源發(fā)生變化時(shí)觸發(fā)回調(diào)函數(shù),第三個(gè)參數(shù)是options。其默認(rèn)行為與 Vue 2.x 有所不同:

      5. lazy:是否會(huì)在組件創(chuàng)建時(shí)就調(diào)用一次回調(diào)函數(shù),與 Vue 2.x 相反,lazy默認(rèn)是false,默認(rèn)會(huì)在組件創(chuàng)建時(shí)調(diào)用一次。
      6. deep:與 Vue 2.x 的 deep 一致
      7. flush:有三個(gè)可選值,分別為 'post'(在渲染后,即nextTick后才調(diào)用回調(diào)函數(shù)),'pre'(在渲染前,即nextTick前調(diào)用回調(diào)函數(shù)),'sync'(同步觸發(fā))。默認(rèn)值為'post'。
      8. // double 是一個(gè)計(jì)算包裝對(duì)象
        const double = computed(() => count.value * 2);
        
        watch(double, value => {
         console.log('double the count is: ', value);
        }); // -> double the count is: 0
        
        count.value++; // -> double the count is: 2
        
        

        當(dāng)watch多個(gè)被包裝對(duì)象屬性時(shí),參數(shù)均可以通過(guò)數(shù)組的方式進(jìn)行傳遞,同時(shí),與 Vue 2.x 的vm.$watch一樣,watch返回取消監(jiān)聽(tīng)的函數(shù):

        const stop = watch(
         [valueA, () => valueB.value],
         ([a, b], [prevA, prevB]) => {
         console.log(`a is: ${a}`);
         console.log(`b is: ${b}`);
         }
        );
        stop();
        

        注意:在RFC:Function-based component API初稿中,有提到effect-cleanup,是用于清理一些特殊情況的副作用的,目前已經(jīng)在提案中被取消了。

        生命周期

        所有現(xiàn)有的生命周期都有對(duì)應(yīng)的鉤子函數(shù),通過(guò)onXXX的形式創(chuàng)建,但有一點(diǎn)不同的是,destoryed鉤子函數(shù)需要使用unmounted代替:

        import { onMounted, onUpdated, onUnmounted } from 'vue-function-api';
        
        const MyComponent = {
         setup() {
         onMounted(() => {
         console.log('mounted!');
         });
         onUpdated(() => {
         console.log('updated!');
         });
         // destroyed 調(diào)整為 unmounted
         onUnmounted(() => {
         console.log('unmounted!');
         });
         },
        };
        
        

        一些思考

        上面的詳解部分,主要抽取的是 Vue Function API 的常見(jiàn)部分,并非RFC:Function-based component API的全部,例如其中的依賴注入,TypeScript類(lèi)型推導(dǎo)等優(yōu)勢(shì),在這里,由于篇幅有限,想要了解更多的朋友,可以點(diǎn)開(kāi)RFC:Function-based component API查看。個(gè)人也在Function-based component API討論區(qū)看到了更多地一些意見(jiàn):

      9. 由于底層設(shè)計(jì),在setup取不到組件實(shí)例this的問(wèn)題,這個(gè)問(wèn)題在筆者嘗試體驗(yàn)時(shí)也遇到了,期待正式發(fā)布的 Vue 3.x 能夠改進(jìn)這個(gè)問(wèn)題。
      10. 對(duì)于基本類(lèi)型的值必須使用包裝對(duì)象的問(wèn)題:在 RFC 討論區(qū),為了同時(shí)保證TypeScript類(lèi)型推導(dǎo)、復(fù)用性和保留Vue的數(shù)據(jù)監(jiān)聽(tīng),包裝屬性必須使用.value來(lái)取值是討論最激烈的
      11. 關(guān)于包裝對(duì)象value和state方法命名不清晰可能導(dǎo)致開(kāi)發(fā)者誤導(dǎo)等問(wèn)題,已經(jīng)在Amendment proposal to Function-based Component API這個(gè)提議中展開(kāi)了討論:
      12. setup() {
         const state = reactive({
         count: 0,
         });
        
         const double = computed(() => state.count * 2);
        
         function increment() {
         state.count++;
         }
        
         return {
         ...toBindings(state), // retains reactivity on mutations made to `state`
         double,
         increment,
         };
        }
        
        
      13. 引入reactive API 和 binding API,其中reactive API 類(lèi)似于 state API , binding API 類(lèi)似于 value API。
      14. 之前使用的方法名state在 Vue 2.x 中可能被用作組件狀態(tài)對(duì)象,導(dǎo)致變量命名空間的沖突問(wèn)題,團(tuán)隊(duì)認(rèn)為將state API 更名為 reactive 更為優(yōu)雅。開(kāi)發(fā)者能夠?qū)懗鯿onst state = ... ,然后通過(guò)state.xxxx這種方式來(lái)獲取組件狀態(tài),這樣也相對(duì)而言自然一些。
      15. value方法用于封裝基本類(lèi)型時(shí),確實(shí)會(huì)出現(xiàn)不夠優(yōu)雅的.value的情況,開(kāi)發(fā)者可能會(huì)在直接對(duì)包裝對(duì)象取值時(shí)忘記使用.value,修正方案提出的 reactive API,其含義是創(chuàng)建響應(yīng)式對(duì)象,初始化狀態(tài)state就使用reactive創(chuàng)建,可保留每項(xiàng)屬性的getter和setter,這么做既滿足類(lèi)型推導(dǎo),也可以保留響應(yīng)式引用,從而可在不同模塊中共享狀態(tài)值的引用。
      16. 但reactive可能導(dǎo)致下面的問(wèn)題,需要引入binding API。 解決,如使用reactive創(chuàng)建的響應(yīng)式對(duì)象,對(duì)其使用拓展運(yùn)算符...時(shí),則會(huì)丟失對(duì)象的getter和setter,提供toBindings方法能夠保留狀態(tài)的響應(yīng)式。
      17. 下一篇文章中,筆者將閱讀vue-function-api的核心部分代碼原理,包括setup、observable、lifecycle等,從內(nèi)部探索 Vue Function API 可能帶給我們的改變。

        當(dāng)然,目前 Vue Function API 還處在討論階段,Vue 3.0 還處在開(kāi)發(fā)階段,還是期待下半年 Vue 3.0 的初版問(wèn)世吧,希望能給我們帶來(lái)更多的驚喜。

        聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        Vue 3.0 前瞻Vue Function API新特性體驗(yàn)

        Vue 3.0 前瞻Vue Function API新特性體驗(yàn):最近 Vue 官方公布了 Vue 3.0 最重要的RFC:Function-based component API,并發(fā)布了兼容 Vue 2.0 版本的 plugin:vue-function-api,可用于提前體驗(yàn) Vue 3.0 版本的 Function-based component API。筆者出于學(xué)習(xí)的目的,提前在
        推薦度:
        標(biāo)簽: VUE API 體驗(yàn)
        • 熱門(mén)焦點(diǎn)

        最新推薦

        猜你喜歡

        熱門(mén)推薦

        專(zhuān)題
        Top
        主站蜘蛛池模板: 成人毛片免费观看视频| 在线看片免费不卡人成视频| 亚洲精品综合久久| 鲁死你资源站亚洲av| 女性自慰aⅴ片高清免费| 亚洲中文无码亚洲人成影院| 97性无码区免费| 亚洲av无码不卡久久| 巨胸喷奶水视频www网免费| 亚洲国产成人综合精品| 免费人妻av无码专区| 一本一道dvd在线观看免费视频| 亚洲精品无码成人片在线观看 | 亚洲午夜无码片在线观看影院猛 | 久久久久国色av免费看| 久久亚洲国产精品| 免费福利视频导航| 亚洲精品宾馆在线精品酒店| 日本免费福利视频| 中文字幕成人免费高清在线| 亚洲欧洲在线观看| 成人毛片免费观看视频在线 | 精品国产亚洲AV麻豆| 亚洲?V无码成人精品区日韩| a级毛片高清免费视频| 亚洲国产精品综合福利专区| 在线观看国产情趣免费视频| xvideos永久免费入口| 亚洲人成网站影音先锋播放| 亚洲精品动漫免费二区| 免费人成大片在线观看播放| 久久精品国产96精品亚洲 | 一级特级aaaa毛片免费观看| 亚洲AV无码第一区二区三区| 国产卡二卡三卡四卡免费网址| 国产精品亚洲а∨无码播放麻豆| 国产精品亚洲片在线| 亚洲中文无码永久免费| 亚洲第一视频在线观看免费| 亚洲影视自拍揄拍愉拍| 久久国产成人亚洲精品影院|