整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          從零開始學(xué)Vue-vue模板和組件

          我們?cè)谇懊娴恼鹿?jié)中已經(jīng)了解了如何在屏幕上以文本內(nèi)容的形式獲得輸出。在本文中我們將學(xué)習(xí)如何在屏幕上以HTML模板的形式獲得輸出。我們先看一段代碼好來(lái)幫助我們理解。

          //index.html
          <!DOCTYPE html>
          <html lang="en">
           <head>
           <meta charset="UTF-8" />
           <meta name="viewport" content="width=device-width, initial-scale=1.0" />
           <meta http-equiv="X-UA-Compatible" content="ie=edge" />
           <title>vue模板和組件</title>
           </head>
           <body>
           <div id="vue_det">
           <h1>姓名 : {{ name }}</h1>
           <div>{{ htmlcontent }}</div>
           </div>
           <script src="https://cdn.jsdelivr.net/npm/vue"></script>
           <script type="text/javascript" src="js/app.js"></script>
           </body>
          </html>
          
          //js/app.js+
          var vm = new Vue({
           el: '#vue_det',
           data: {
           name: "孫悟空",
           htmlcontent: "<div><h1>Vue Js Template</h1></div>"
           }
          })
          

          使用live-server啟動(dòng)項(xiàng)目得到如下結(jié)果

          因?yàn)槲覀兪褂昧瞬逯担簿褪请p括號(hào),我們?cè)跒g覽器中就真實(shí)的顯示了html內(nèi)容,這顯然和我們想要渲染html是不同的,我們希望它在瀏覽器能顯示html渲染的內(nèi)容。

          v-html

          為了解決上面的問(wèn)題,我們不得不適用v-html指令,只要我們將v-html屬性分配給html元素,vue就會(huì)知道將其作為html內(nèi)容輸出,我們嘗試下:

          <div id="vue_det">
           <h1>姓名 : {{ name }}</h1>
           <div v-html="htmlcontent"></div>
           </div>
          

          得到了如下結(jié)果

          從瀏覽器調(diào)試可以看出

          與app.js中填寫的html字符串表現(xiàn)得相同

          屬性分配

          我們已經(jīng)了解了如何將HTML模板添加到DOM。現(xiàn)在,我們將實(shí)現(xiàn)如何向現(xiàn)有的HTML元素添加屬性。想象一下,我們?cè)贖TML文件中有一個(gè)圖像標(biāo)記,我們想要分配src屬性,舉例,直接看代碼

           <div id="vue_det">
           <h1>姓名 : {{ name }}</h1>
           <div v-html="htmlcontent"></div>
           <img src="" width="300" height="250" />
           </div>
          

          img標(biāo)簽的src是空的,我們將src放到j(luò)s的數(shù)據(jù)對(duì)象中

          var vm = new Vue({
           el: '#vue_det',
           data: {
           name: "孫悟空",
           htmlcontent: "<div><h1>Vue Js Template</h1></div>",
           imgsrc: './img/img.jpg'
           }
          })
          

          然后我們修改index.html

          <img src="{{ imgsrc }}" width="300" height="250" />
          

          結(jié)果如下

          好像哪里不對(duì),其實(shí)不是,在vue中,我們綁定屬性用v-bind指令

           <img v-bind:src="imgsrc" width="300" height="250" />
          

          可以看到我們?yōu)g覽器中渲染的html

          組件

          Vue組件是VueJS的重要功能之一,可以創(chuàng)建自定義元素,可以在HTML中重復(fù)使用。讓我們使用一個(gè)示例并創(chuàng)建一個(gè)組件。

          //index.html
          <!DOCTYPE html>
          <html lang="en">
           <head>
           <meta charset="UTF-8" />
           <meta name="viewport" content="width=device-width, initial-scale=1.0" />
           <meta http-equiv="X-UA-Compatible" content="ie=edge" />
           <title>vue模板和組件</title>
           </head>
           <body>
           <div id="component_test">
           <testcomponent></testcomponent>
           </div>
           <div id="component_test1">
           <testcomponent></testcomponent>
           </div>
           <script src="https://cdn.jsdelivr.net/npm/vue"></script>
           <script type="text/javascript" src="js/app.js"></script>
           </body>
          </html>
          


          //js/app.js
          Vue.component('testcomponent', {
           template: '<div><h1>This is coming from component</h1></div>'
          });
          var vm = new Vue({
           el: '#component_test'
          });
          var vm1 = new Vue({
           el: '#component_test1'
          });
          

          我們創(chuàng)建了兩個(gè)div,id分別是component_test和component_test1,在app.js中我們創(chuàng)建了兩個(gè)Vue實(shí)例,外加一個(gè)Vue組件,要想創(chuàng)建組件,它的語(yǔ)法是

          Vue.component('nameofthecomponent',{ // options});
          

          創(chuàng)建組件后,組件的名稱將成為自定義元素,并且可以在創(chuàng)建的Vue實(shí)例元素中使用相同的名稱,在app.js文件中創(chuàng)建的組件中,我們添加了一個(gè)模板,我們已為其分配了HTML代碼。這是一種注冊(cè)全局組件的方法,可以將其作為任何vue實(shí)例的一部分,我們發(fā)現(xiàn)這時(shí)候?yàn)g覽器變成了

          組件被賦予自定義元素標(biāo)記,即<testcomponent> </ testcomponent>。但是,當(dāng)我們?cè)跒g覽器中檢查相同內(nèi)容時(shí),我們發(fā)現(xiàn)結(jié)果沒(méi)有自定義的元素,如以下屏幕截圖所示。

          我們也可以將組件作為vue實(shí)例的一部分

          var vm = new Vue({
           el: '#component_test',
           components:{
           'testcomponent': {
           template : '<div><h1>This is coming from component</h1></div>'
           }
           }
          });
          

          這是本地注冊(cè)組件,組件只是vue實(shí)例的一部分。到目前為止我們已經(jīng)基本組件的實(shí)現(xiàn)。現(xiàn)在我們來(lái)繼續(xù)擴(kuò)展。

          // js/app.js
          Vue.component('testcomponent', {
           template: '<div v-on:mouseover = "changename()" v-on:mouseout = "originalname();"><h1>Custom Component created by <span id = "name">{{name}}</span></h1></div>',
           data: function () {
           return {
           name: "tom"
           }
           },
           methods: {
           changename: function () {
           this.name = "bob";
           },
           originalname: function () {
           this.name = "tom";
           }
           }
          });
          var vm = new Vue({
           el: '#component_test'
          });
          var vm1 = new Vue({
           el: '#component_test1'
          });
          

          在上面的app.js文件中,我們添加了一個(gè)函數(shù),它返回一個(gè)對(duì)象。該對(duì)象具有name屬性,該屬性被賦值為'tom'。盡管這里data是函數(shù),我們也可以像直接在Vue實(shí)例中使用其屬性,此外這里還添加了兩個(gè)函數(shù),在changename中,我們更改name屬性,在originalname中我們將其重置為原始名稱,有關(guān)事件我們后面在討論,這段代碼的結(jié)果是:

          因?yàn)榉峙淞薽ouseover和mouseout事件,當(dāng)鼠標(biāo)懸停在tom上時(shí),會(huì)將tom改成bob

          動(dòng)態(tài)組件

          使用關(guān)鍵字<component> </ component>創(chuàng)建動(dòng)態(tài)組件,并使用屬性綁定,如下

          <component v-bind:is = "view"></component>
          
          //index.html
          <!DOCTYPE html>
          <html lang="en">
           <head>
           <meta charset="UTF-8" />
           <meta name="viewport" content="width=device-width, initial-scale=1.0" />
           <meta http-equiv="X-UA-Compatible" content="ie=edge" />
           <title>vue模板和組件</title>
           </head>
           <body>
           <div id="databinding">
           <component v-bind:is="view"></component>
           </div>
           <script src="https://cdn.jsdelivr.net/npm/vue"></script>
           <script type="text/javascript" src="js/app.js"></script>
           </body>
          </html>
          
          //app.js
          var vm = new Vue({
           el: "#databinding",
           data: {
           view: "component1"
           },
           components: {
           component1: {
           template:
           '<div><span style = "font-size:25;color:red;">Dynamic Component</span></div>'
           }
           }
          });
          

          瀏覽器已顯示值:

          提:已創(chuàng)建vue項(xiàng)目,未創(chuàng)建請(qǐng)參考 https://www.toutiao.com/article/7398100974524449330/

          步驟 1:在項(xiàng)目目錄下,安裝 Element UI(Element UI 是一個(gè)基于 Vue.js 的組件庫(kù),它提供了一套為開發(fā)者設(shè)計(jì)和實(shí)現(xiàn)用戶界面的解決方案。Element UI 提供了大量預(yù)設(shè)計(jì)的組件,如按鈕、輸入框、選擇器等,這可以幫助開發(fā)者快速構(gòu)建應(yīng)用程序界面。

          Element ui的手冊(cè)網(wǎng)站: https://element-plus.org/zh-CN/guide/installation.html )

          操作:在vscode中打開項(xiàng)目根目錄,按ctrl+~鍵打開終端,在終端中輸入npm install element-plus --save

          步驟2:在 main.js 中引入 Element Plus 和相關(guān)的樣式(此方式是全局引入即將Element所有的組件引入):

          import { createApp } from 'vue';

          import App from './App.vue';

          import router from './router'; // 導(dǎo)入路由

          import ElementPlus from 'element-plus'; // 導(dǎo)入 Element Plus

          import 'element-plus/dist/index.css'; // 導(dǎo)入 Element Plus 的 CSS 樣式

          // 創(chuàng)建 Vue 應(yīng)用實(shí)例

          const app = createApp(App);

          // 使用路由

          app.use(router);

          // 使用 Element Plus 插件

          app.use(ElementPlus);

          // 掛載應(yīng)用

          app.mount('#app');

          步驟3: 使用 Element Plus 組件

          打開網(wǎng)站的“組件”界面,在左側(cè)選擇要添加的組件,如:按鈕;在右側(cè)出現(xiàn)各種樣式的按鈕,點(diǎn)擊樣式右下角的“<>”顯示出源代碼,復(fù)制源代進(jìn)行調(diào)用。

          實(shí)操:我們可以在新建一個(gè)dome.vue頁(yè)面,使用一個(gè)按鈕組件:

          (1)創(chuàng)建新頁(yè)面,選中views右擊點(diǎn)擊“新建文件”在文件中輸入“dome.vue

          (2)選擇按鈕樣式,這里我選擇success按鈕,復(fù)制相對(duì)應(yīng)的代碼<el-button type="success">Success</el-button>

          (3)將代碼添加到頁(yè)面中

          <template>

          <el-button type="success">Success</el-button>

          </template>

          <script setup>


          </script>

          <style>

          /* 這里可以添加樣式 */

          </style>

          文分享自華為云社區(qū)《DTSE Tech Talk | 6個(gè)實(shí)例帶你解讀TinyVue 組件庫(kù)跨框架技術(shù)-云社區(qū)-華為云》,作者: 華為云社區(qū)精選。

          在DTSE Tech Talk 《 手把手教你實(shí)現(xiàn)mini版TinyVue組件庫(kù) 》的主題直播中,華為云前端開發(fā)DTSE技術(shù)布道師阿健老師給開發(fā)者們展開了組件庫(kù)跨框架的討論,同時(shí)針對(duì)TinyVue組件庫(kù)的關(guān)鍵技術(shù)進(jìn)行了剖析,并通過(guò)項(xiàng)目實(shí)戰(zhàn)演示了一份源碼編譯出2個(gè)不同Vue 框架的組件。最后針對(duì)框架間的差異,也給出了相應(yīng)的技術(shù)方案,幫助開發(fā)者們實(shí)戰(zhàn)完成組件庫(kù)跨框架。

          直播鏈接:https://bbs.huaweicloud.com/live/DTT_live/202404171630.html

          一、手把手帶你實(shí)現(xiàn)mini 版 TinyVue

          當(dāng)前實(shí)現(xiàn)組件庫(kù)的跨框架技術(shù),是提升Web頁(yè)面開發(fā)效率與應(yīng)用靈活性的重要手段。本次直播的實(shí)戰(zhàn)環(huán)節(jié),用300行代碼模擬了 TinyVue 組件庫(kù)的跨框架實(shí)現(xiàn),開發(fā)者可以在mini 版組件庫(kù)中,復(fù)現(xiàn)跨框架及多端適配兩大功能。同時(shí)通過(guò)本期的實(shí)操環(huán)節(jié),也給開發(fā)者呈現(xiàn)一個(gè)明確且詳盡的實(shí)現(xiàn)流程,協(xié)助大家更好的理解并掌握跨框架技術(shù)并運(yùn)用到實(shí)際工作中。

          具體源碼可參考: https://github.com/opentiny/mini-tiny-vue

          二、為什么要實(shí)現(xiàn)組件庫(kù)跨框架呢?

          目前,Vue擁有Vue2和Vue3兩大主要分支,它們?cè)陂_發(fā)上并不兼容。Vue2還可以進(jìn)一步細(xì)分為2.6及之前的版本和Vue2.7這兩個(gè)小分支,其中Vue2.7作為2.6與Vue3之間的過(guò)渡版本,在開發(fā)上起著橋梁作用。

          對(duì)于現(xiàn)有項(xiàng)目來(lái)講,如果遷移到Vue3,難免存在API及組件功能不同步的情況,因此遷移過(guò)程將存在一定的成本及風(fēng)險(xiǎn)。而在當(dāng)前的Vue生態(tài)中,諸如Antdesign和Element等知名組件庫(kù)都推出了支持Vue2和Vue3的組件。然而這些官網(wǎng)文檔和API卻并不通用,這意味著實(shí)際上是提供了兩個(gè)獨(dú)立的組件庫(kù)來(lái)實(shí)現(xiàn)跨框架支持的。

          作為致力于實(shí)現(xiàn)跨框架的TinyVue組件庫(kù),旨在實(shí)現(xiàn)跨不同版本的Vue框架兼容性,其獨(dú)特之處在于采用單份源代碼策略,通過(guò)智能編譯技術(shù),能夠同時(shí)生成適用于Vue 2.6、2.7版本以及Vue3版本的組件包。這意味著開發(fā)者只需維護(hù)同一個(gè)官方網(wǎng)站,并提供一套標(biāo)準(zhǔn)化的API接口,即可滿足多版本Vue用戶的需求。這種設(shè)計(jì)有效地減少了TinyVue組件庫(kù)的維護(hù)成本和未來(lái)技術(shù)遷移的風(fēng)險(xiǎn)。

          三、關(guān)鍵技術(shù)剖析

          首先以一個(gè)button組件為例,組件的左上部分是模板,作為組件的入口,它集成了適配層、renderless邏輯以及theme樣式(此處暫不涉及theme部分)。值得注意的是,組件內(nèi)部并未包含任何邏輯代碼,所有邏輯均被抽離至renderless中,這里可以按照下圖所示觀察其調(diào)用關(guān)系。

          • 從vue文件(即組件的入口文件)開始,引入了適配層中的setup函數(shù)和無(wú)狀態(tài)的renderless函數(shù)。setup函數(shù)的調(diào)用過(guò)程中,將包含狀態(tài)的props和context,以及無(wú)狀態(tài)的純函數(shù)renderless一并傳入。
          • 然后進(jìn)入setup函數(shù)內(nèi)部,適配層中的tools函數(shù)會(huì)構(gòu)造一個(gè)對(duì)象,用于抹平框架之間的差異,并將該對(duì)象傳遞給renderless函數(shù)。這樣,在renderless函數(shù)中,可以放心地引用該對(duì)象,而無(wú)需擔(dān)心組件是在vue2還是vue3環(huán)境下運(yùn)行。
          • 接下來(lái)調(diào)用純函數(shù)renderless。它為每個(gè)組件構(gòu)造一個(gè)與當(dāng)前組件相關(guān)聯(lián)的state和api,這些都是有狀態(tài)的值。隨后,這些狀態(tài)值被返回給適配層。
          • 最后適配層將這些狀態(tài)值傳遞給模板進(jìn)行綁定。具體而言,state被綁定到模板的數(shù)據(jù)值上,而api則被綁定到模板的事件上。

          整體來(lái)看,調(diào)用過(guò)程就像一個(gè)管道,數(shù)據(jù)從模板開始流動(dòng),經(jīng)過(guò)邏輯處理,再流回到模板上。在這個(gè)過(guò)程中,它流經(jīng)的適配層巧妙地抹平了框架之間的差異,正是TinyVue跨框架的精妙所在。

          四、如何解決框架差異統(tǒng)一,實(shí)現(xiàn)跨框架?

          1、框架間的差異是什么?

          Vue3是一次全新的框架升級(jí),所以它的語(yǔ)法以及內(nèi)部實(shí)現(xiàn),都發(fā)生了很大的變化,這些是在開發(fā)跨框架組件庫(kù)時(shí)必須考慮的問(wèn)題。而在長(zhǎng)期的跨框架組件庫(kù)的開發(fā)中,可能會(huì)遇到眾多的框架差異,具體可以將這些差異歸結(jié)為2大類:

          (1)框架對(duì)外差異,直接影響到模板的開發(fā)以及某些語(yǔ)法。例如:

          • 模板語(yǔ)法差異
          • 生命周期名稱變化
          • 移除了事件修飾符、過(guò)濾器、消息訂閱
          • v-model 語(yǔ)法糖差異
          • 指令,動(dòng)畫組件的差異

          (2)框架內(nèi)部差異,主要是Vue runtime層面的實(shí)現(xiàn)差異。在開發(fā)跨框架組件過(guò)程中,需要訪問(wèn)組件內(nèi)部某些變量時(shí)可能會(huì)遇到,例如:

          • 組件實(shí)例的差異
          • Vnode結(jié)構(gòu)的差異
          • 移除了$children, $scopedSlots等

          2、 框架差異及應(yīng)對(duì)方案

          (1)響應(yīng)式函數(shù)引入包差異:

          在Vue 2.6 中引入響應(yīng)函數(shù)

          import { reactive, ref, watch, ... } from '@vue/composition-api'

          在Vue 3 中引入響應(yīng)函數(shù)

          import { reactive, ref, watch, ... } from 'vue'

          解決方案:通過(guò)在適配層暴露一個(gè)hooks變量,統(tǒng)一響應(yīng)式函數(shù)的訪問(wèn),代碼如下

          // adapter/vue2/index.js
          
          import * as hooks from '@vue/composition-api'
          // adapter/vue3/index.js
          
          import * as hooks from 'vue'
          // adapter/index.js
          
          export { hooks }

          (2)VNode和 h 函數(shù)的差異:

          在Vue 2.6中,渲染函數(shù)的 VNode 參數(shù)結(jié)構(gòu)

          {
          
            staticClass: 'button',
          
            class: { 'is-outlined': isOutlined },
          
            staticStyle: { color: '#34495E' },
          
            style: { backgroundColor: buttonColor },
          
            attrs: { id: 'submit' },
          
            domProps: { innerHTML: '' },
          
            on: { click: submitForm },
          
            key: 'submit-button'
          
          }

          在Vue 3 中,渲染函數(shù)的 VNode 參數(shù)結(jié)構(gòu)是扁平的

          {
          
            class: ['button', { 'is-outlined': isOutlined }],
          
            style: [{ color: '#34495E' }, { backgroundColor: buttonColor }],
          
            id: 'submit',
          
            innerHTML: '',
          
            onClick: submitForm,
          
            key: 'submit-button'
          
          }

          解決方案:通過(guò)在適配層暴露一個(gè)h函數(shù),讓Vue3框架也能支持Vue2的參數(shù)格式。這樣就能統(tǒng)一h 函數(shù)的用法,同時(shí)讓在Vue2時(shí)期開發(fā)的組件在Vue3框架下兼容運(yùn)行。

          // adapter/vue2/index.js
          
          const h = hooks.h
          // adapter/vue3/index.js 
          
          const h = (component, propsData, childData) => {
          
            // 代碼有省略...... 
          
            let props = {}
          
            let children = childData
            if (propsData && typeof propsData === 'object' && !Array.isArray(propsData)) {
          
              props = parseProps(propsData)
          
              propsData.scopedSlots && (children = propsData.scopedSlots)
          
            } else if (typeof propsData === 'string' || Array.isArray(propsData)) {
          
              childData = propsData
          
            }
          
            return hooks.h(component, props, children)
          
          }
          // adapter/index.js
          
          export { h }

          (3)v-model的差異:

          在Vue 2.6中,在組件上使用 v-model 相當(dāng)于綁定 value 屬性和 input 事件

            <ChildComponent v-model="pageTitle" />
          
            <!-- 會(huì)編譯為: -->
          
            <ChildComponent :value="pageTitle" @input="pageTitle = $event" />

          在Vue 3 中,v-model 相當(dāng)于綁定了 modelValue 屬性和 update:modelValue 事件

            <ChildComponent v-model="pageTitle" />
          
            <!-- 會(huì)編譯為: -->
          
            <ChildComponent :modelValue="pageTitle" @update:modelValue="pageTitle = $event" />

          解決方案:通過(guò)Vue2中聲明 model的option 選項(xiàng),來(lái)自定義Vue2框架下v-model 的默認(rèn)綁定 prop 和 event 。

          defineComponent({
          
            model: {
          
              prop: 'modelValue', // 默認(rèn)值為 value
          
              event: 'update:modelValue' // 默認(rèn)值為 input
          
            },
          
            props: {
          
              modelValue: String
          
            } // ...
          
          })

          (4)slots的差異:

          在Vue 2.6中,有普通插槽 slots 和 作用域插槽 scopedSlots

          // 普通插槽為對(duì)象,可以直接使用
          
          this.$slots.mySlot
          // 作用域插槽為函數(shù),要按函數(shù)來(lái)調(diào)用
          
          this.$scopedSlots.header()

          在Vue 3 中,統(tǒng)一為 slots 函數(shù)的形式

          // 將所有 scopedSlots 替換為 slots
          
          this.$slots.header()
          // 將原有 slots 改為函數(shù)調(diào)用方式
          
          this.$slots.mySlot()

          解決方案:通過(guò)構(gòu)建一個(gè)vm.$slots屬性, 來(lái)統(tǒng)一2個(gè)框架中,訪問(wèn)slots的訪問(wèn)。

          // adapter/vue2/index.js
          
            Object.defineProperties(vm, {
          
               // ......
          
              $slots: { get: () => instance.proxy.$scopedSlots },
          
              $scopedSlots: { get: () => instance.proxy.$scopedSlots },
          
            })
             // adapter/vue3/index.js
          
             Object.defineProperties(vm, {
          
              // ......
          
              $slots: { get: () => instance.slots },
          
              $scopedSlots: { get: () => instance.slots },
          
            })

          我們?cè)趘m下,還暴露了許多框架runtime層面上的組件屬性,用于抹平跨Vue框架的差異。在開發(fā)跨框架組件時(shí),要使用vm來(lái)訪問(wèn)組件,避免直接訪問(wèn)組件的instance。

          // 創(chuàng)建一個(gè)Vue2 運(yùn)行時(shí)的兼容 vm 對(duì)象
          
          const createVm = (vm, _instance) => {
          
            const instance = _instance.proxy
            Object.defineProperties(vm, {
          
              $attrs: { get: () => instance.$attrs },
          
              $listeners: { get: () => instance.$listeners },
          
              $el: { get: () => instance.$el },
          
              $parent: { get: () => instance.$parent },
          
              $children: { get: () => instance.$children },
          
              $nextTick: { get: () => hooks.nextTick },
          
              $on: { get: () => instance.$on.bind(instance) },
          
              $once: { get: () => instance.$once.bind(instance) },
          
              $off: { get: () => instance.$off.bind(instance) },
          
              $refs: { get: () => instance.$refs },
          
              $slots: { get: () => instance.$scopedSlots },
          
              $scopedSlots: { get: () => instance.$scopedSlots },
          
              $set: { get: () => instance.$set }
          
            })
            return vm
          
          }
          
          // 創(chuàng)建一個(gè)Vue3 運(yùn)行時(shí)的兼容 vm 對(duì)象
          
          const createVm = (vm, instance) => {
            Object.defineProperties(vm, {
          
              $attrs: { get: () => $attrs },
          
              $listeners: { get: () => $listeners },
          
              $el: { get: () => instance.vnode.el },
          
              $parent: { get: () => instance.parent },
          
              $children:{get:()=>genChild(instance.subTree)},
          
              $nextTick: { get: () => hooks.nextTick },
          
              $on: { get: () => $emitter.on },
          
              $once: { get: () => $emitter.once },
          
              $off: { get: () => $emitter.off },
          
              $refs: { get: () => instance.refs },
          
              $slots: { get: () => instance.slots },
          
              $scopedSlots: { get: () => instance.slots },
          
              $set: { get: () => $set }
          
            })
            return vm
          
          }

          (5)指令的差異:

          Vue3的指令生命周期的名稱變化了, 但指令的參數(shù)基本不變

          解決方案:在開發(fā)指令對(duì)象時(shí),通過(guò)補(bǔ)齊指令周期,讓指令對(duì)象同時(shí)支持Vue2 和 Vue3

          (6)動(dòng)畫類型的差異:

          解決方案:在全局的動(dòng)畫類名文件中,同時(shí)補(bǔ)齊2個(gè)框架下的類名,讓動(dòng)畫類同時(shí)支持Vue2 和 Vue3的Transition組件

          // 此處同時(shí)寫了 -enter \  -enter-from 的類名,所以它同時(shí)支持vue2,vue3的 Transition 組件。
          
          .fade-in-linear-enter,
          
          .fade-in-linear-enter-from,
          
          .fade-in-linear-leave-to {
          
            opacity: 0;
          
          }

          在構(gòu)建TinyVue跨框架組件庫(kù)的過(guò)程中,團(tuán)隊(duì)集中攻克了多個(gè)Vue框架間的關(guān)鍵差異點(diǎn),其中六項(xiàng)尤為突出且具有代表性。

          開發(fā)TinyVue跨框架組件庫(kù)時(shí),面對(duì)Vue2與Vue3的重要區(qū)別,我們確立了兩個(gè)核心原則:一是“求同去異”,即在編寫組件時(shí)選用兩框架都支持的通用語(yǔ)法,如因Vue2不支持多根節(jié)點(diǎn)組件而統(tǒng)一采用單根節(jié)點(diǎn)設(shè)計(jì);二是“兼容并包”,通過(guò)構(gòu)建適配層隱藏框架間的差異,提供統(tǒng)一接口,無(wú)需開發(fā)者手動(dòng)判斷框架版本,這樣他們可以更專注于邏輯開發(fā)。在指令對(duì)象和動(dòng)畫類名等細(xì)節(jié)方面,同樣貫徹這一簡(jiǎn)化差異、廣泛兼容的理念。

          關(guān)注#華為云開發(fā)者聯(lián)盟# 點(diǎn)擊下方,第一時(shí)間了解華為云新鮮技術(shù)~

          華為云博客_大數(shù)據(jù)博客_AI博客_云計(jì)算博客_開發(fā)者中心-華為云


          主站蜘蛛池模板: 国产SUV精品一区二区88| 国产成人欧美一区二区三区| 亚洲精品国产suv一区88| 久久久精品人妻一区二区三区| 日本一区二区不卡在线| 奇米精品视频一区二区三区| 日韩精品一区二区亚洲AV观看| 国产精品一区在线麻豆| 国产一区二区三区美女| 国产一区二区三区不卡观| 亚洲av成人一区二区三区 | 亚洲V无码一区二区三区四区观看 亚洲爆乳精品无码一区二区三区 亚洲爆乳无码一区二区三区 | 亚洲一区二区三区在线 | 国产精品电影一区二区三区| 一区二区三区视频网站| 久久久精品人妻一区二区三区| 亚洲日韩一区精品射精| 国产精品 视频一区 二区三区| 风间由美性色一区二区三区| 日韩精品一区二区三区中文版| 中文字幕一区二区三区有限公司| 91福利一区二区| 琪琪see色原网一区二区| 亚洲AV无码一区二区三区系列| 天堂一区二区三区在线观看| 夜色阁亚洲一区二区三区| 亚洲国产一区在线观看| 国产成人精品久久一区二区三区av| 无码精品人妻一区二区三区人妻斩| 午夜一区二区免费视频| 日本免费电影一区二区| 精品免费AV一区二区三区| 精品国产a∨无码一区二区三区| 一区视频在线播放| 国产伦精品一区二区三区不卡| 国产亚洲无线码一区二区| 精品综合一区二区三区| 在线精品视频一区二区| 国产成人精品视频一区二区不卡| 日韩成人一区ftp在线播放| 亚洲一区二区三区无码国产|