手寫Vue內(nèi)置組件component的實(shí)現(xiàn)示例
最近在復(fù)習(xí)Vue的源碼,今天帶大家手寫實(shí)現(xiàn)一下Vue內(nèi)置組件component,比較簡單,最近面試有被問到。
前言
Vue
大家都很熟悉,除了原生的組件,其自己也封裝了一下內(nèi)置組件,比如component
,transition
,keep-alive
等等。
component
算是用的比較多的了,當(dāng)我們遇到需要根據(jù)不同條件顯示不同組件的時候,一般都是用component
來實(shí)現(xiàn)。當(dāng)然你也可以v-if,v-else-if,v-else
,就顯的比較笨了。
大家如果沒用過,可以先自己嘗試一下這個component
組件。最主要的就是它有一個is
屬性,你給is賦予什么組件名,它就渲染什么組件。
內(nèi)置組件component的使用
我寫一個小demo
演示一下。
先隨意的寫三個組件,A
,B
,C
。
組件內(nèi)容就是aaaa
,bbbb
,cccc
,方便我們辨認(rèn)當(dāng)然渲染的是哪個組件。
然后集體引入,掛載。
視圖內(nèi)容大概這樣寫,需求就是,準(zhǔn)備三個按鈕,點(diǎn)擊哪個按鈕就顯示哪個組件。
<div> <button @click="changeComp('A')">顯示A</button> <button @click="changeComp('B')">顯示B</button> <button @click="changeComp('C')">顯示C</button> </div> <component :is="compList"></component>
compList
提前聲明好,默認(rèn)是A
組件。
data() { return { compList: 'A' }; },
changeComp
函數(shù)內(nèi)容如下:
methods: { changeComp(comp) { this.compList = comp; }, }
OK,這就完事了,大家可以自己試一下,是可以完成既定的需求的。
component組件的原理分析
我們今天的任務(wù)是,了解內(nèi)置組件component
的原理,并手寫實(shí)現(xiàn)一個。
那么component
的實(shí)現(xiàn)原理是怎么樣的呢,這個就需要牽扯一塊比較大的知識鏈了,也是Vue
的核心內(nèi)容。關(guān)于Vue
的虛擬DOM
以及模板編譯的部分內(nèi)容。
簡單來說,Vue
內(nèi)部實(shí)現(xiàn)了一個虛擬DOM
來妥善解決原生DOM
的性能問題。
虛擬DOM與原生DOM
比如我們當(dāng)前需要插入1000
個DOM
節(jié)點(diǎn),如果是原生DOM
來做的話,就是扎扎實(shí)實(shí)的,一個個操作,改變DOM
,DOM
需要被改變1000
次,這對于性能是極大的損耗,造成很多的問題。
虛擬DOM
的原理就是,先在框架內(nèi)部用對象模擬一下原生DOM
的形態(tài),記錄你這1000
次的DOM
操作,最后將DOM
被操作1000
次后的形態(tài)賦給原生DOM
。這樣就能極大的優(yōu)化大量DOM
操作帶來的負(fù)面影響。
然后再來思考一下,我們平時寫的.vue
文件,其實(shí)跟原生寫法是有區(qū)別的,無論是HTML
、JS
還是CSS
,在編寫階段有做了些許的改動,這樣做有助于提高我們的編寫效率。但是瀏覽器是只認(rèn)原生的HTML
、CSS
和JS
的,所以我們編寫的組件內(nèi)容,其實(shí)只是一個template
模板,需要進(jìn)行編譯轉(zhuǎn)換為原生的DOM
才能渲染到瀏覽器上。
而componet
組件其實(shí)就是內(nèi)部做了這個事情,將你傳入的組件, 先轉(zhuǎn)換為虛擬DOM
,然后渲染為真實(shí)DOM
,展示到視圖上。
render函數(shù)的使用
這里面就涉及到一個知識點(diǎn)了,關(guān)于render
函數(shù)的使用,具體的內(nèi)容大家可以去Vue
文檔詳細(xì)了解一下render
函數(shù)。可能大家日常開發(fā)用的比較少,涉及一些偏底層的東西時才會遇到。
我這里只介紹render
函數(shù)做的事情。
它的形態(tài)大概是這個樣式。
render(h) { // return h('A'); return h('div', '6666'); },
render
函數(shù)接收一個參數(shù),比如叫它h
,h
也是一個函數(shù),它的作用就是將傳入的內(nèi)容構(gòu)建為虛擬DOM
,這個傳入的內(nèi)容支持原生的寫法,也支持Vue
組件。
比如我代碼里給出的,h('div', '6666')
,h
函數(shù)就會生成一個div
組件,文本內(nèi)容是666
。被注釋掉的,就是傳入Vue
中自己的寫的組件名字為A
,同樣支持。
但是h
函數(shù)僅僅只是將傳入的內(nèi)容,生成虛擬DOM
,不是真實(shí)的原生DOM
,然后將它return
出去,render
函數(shù)才會將這個虛擬DOM
渲染成為真實(shí)DOM
。
上述關(guān)于render
函數(shù)的內(nèi)容不知道大家是否理解,可以去Vue
官方文檔里,詳細(xì)看一下,然后自己寫寫demo
體驗(yàn)一下,render
函數(shù)算是Vue
進(jìn)階中比較重要的內(nèi)容了。
所以,話說回來,知道了render
函數(shù)這個東西,我們就能夠比較好的實(shí)現(xiàn)component
這個內(nèi)置組件了。component
組件會接收一個屬性is
,is
的值就是我們要渲染的組件。component
組件的內(nèi)容其實(shí)就是進(jìn)行了 Vue組件 => 虛擬DOM => 真實(shí)DOM
,渲染視圖,其實(shí)就通過render
函數(shù)實(shí)現(xiàn)就可以。
嘗試手寫實(shí)現(xiàn)component
話不多說,我們試一下。
因?yàn)榻M件內(nèi)容比較少,所以我們直接使用Vue.component
來編寫組件內(nèi)容。
Vue.component("myComponent", { props: ["is"], render(h) { return h(this.is); }, });
其實(shí)核心代碼就上面這幾行,組件名字是myComponent
,props
的作用就是指定組件要接收的參數(shù)is
。然后編寫一下render
函數(shù),因?yàn)槭卿秩?code>Vue組件,所以直接return h(this.is)
就可以。
將這段代碼寫在JS
里,然后就可以使用了。記得要import Vue from 'vue'
來引入Vue
,因?yàn)槲覀兪峭ㄟ^Vue.component
來編寫組件的。
下面我們試一試,這個myComponent
是否有用。
<div> <button @click="changeComp('A')">顯示A</button> <button @click="changeComp('B')">顯示B</button> <button @click="changeComp('C')">顯示C</button> </div> <component :is="compList"></component> <my-component :is="compList"></my-component>
實(shí)際操作后可以發(fā)現(xiàn),我們自己寫的myComponent
和Vue
內(nèi)置的component
效果是一模一樣的,大家自己也可以試一下。
完整代碼:
<template> <div> <div> <button @click="changeComp('A')">顯示A</button> <button @click="changeComp('B')">顯示B</button> <button @click="changeComp('C')">顯示C</button> </div> <component :is="compList"></component> <my-component :is="compList"></my-component> </div> </template> <script> import Vue from "vue"; import A from "../components/A.vue"; import B from "../components/B.vue"; import C from "../components/C.vue"; Vue.component("myComponent", { props: ["is"], render(h) { return h(this.is); }, }); export default { components: { A, B, C, }, data() { return { compList: 'A' }; }, methods: { changeComp(comp) { this.compList = comp; }, }, }; </script> <style scoped> </style>
總結(jié)
今天的內(nèi)容是帶著大家手寫實(shí)現(xiàn)Vue
的內(nèi)置組件component
,在嘗試實(shí)現(xiàn)某一個東西的時候,就需要先思考它的作用以及內(nèi)部原理。手寫component
的過程比較簡單,但是涉及到了很多Vue
的原理性知識點(diǎn),比如虛擬DOM、render函數(shù)、模板編譯等。
到此這篇關(guān)于手寫Vue內(nèi)置組件component的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Vue內(nèi)置組件component內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue-router 類似Vuex實(shí)現(xiàn)組件化開發(fā)的示例
本篇文章主要介紹了Vue-router 類似Vuex實(shí)現(xiàn)組件化開發(fā)的示例,具有一定的參考價值,有興趣的可以了解一下2017-09-09Vue router-view和router-link的實(shí)現(xiàn)原理
這篇文章主要介紹了Vue router-view和router-link的實(shí)現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Vue3中實(shí)現(xiàn)拖拽和縮放自定義看板 vue-grid-layout的方法
這篇文章主要介紹了Vue3中實(shí)現(xiàn)拖拽和縮放自定義看板 vue-grid-layout的方法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03vue報錯"vue-cli-service‘不是內(nèi)部或外部命令,也不是...”的解決辦法
這篇文章主要介紹了vue報錯"vue-cli-service‘不是內(nèi)部或外部命令,也不是...”的解決辦法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01vue的rules驗(yàn)證部分可以部分又失效的原因及解決方案
vue的rules驗(yàn)證失效,部分可以部分又失效,很多百度都有,但是我這里遇到了一個特別的,那就是prop沒有寫全,導(dǎo)致驗(yàn)證某一個失效,接下來就跟小編一起來看看這個失效的原因和解決方案吧2023-11-11