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