vue中的render函數(shù)、h()函數(shù)、函數(shù)式組件詳解
一、什么是render
官網(wǎng):用于編程式地創(chuàng)建組件虛擬 DOM 樹的函數(shù)。
在我們使用webpack腳手架創(chuàng)建項(xiàng)目時(shí),都能在main.js中看到一個(gè)render函數(shù)
import Vue from 'vue' import App from './App.vue' new Vue({ render: h => h(App) }).$mount('#app')
對(duì)于render函數(shù) es6中寫成了箭頭函數(shù)
es5寫法:
render: function (createElement) { return createElement(App); }
實(shí)際上createElement只是形參用h代表了,h()
是 hyperscript 的簡(jiǎn)稱——意思是“能生成 HTML (超文本標(biāo)記語言) 的 JavaScript”。這個(gè)名字來源于許多虛擬 DOM 實(shí)現(xiàn)默認(rèn)形成的約定。一個(gè)更準(zhǔn)確的名稱應(yīng)該是 createVnode()
,但當(dāng)你需要多次使用渲染函數(shù)時(shí),一個(gè)簡(jiǎn)短的名字會(huì)更省力。
二、vue中的render
字符串模板的代替方案,允許你發(fā)揮 JavaScript 最大的編程能力。該渲染函數(shù)接收一個(gè) createElement
方法作為第一個(gè)參數(shù)用來創(chuàng)建 VNode
。
如果組件是一個(gè)函數(shù)組件,渲染函數(shù)還會(huì)接收一個(gè)額外的 context
參數(shù),為沒有實(shí)例的函數(shù)組件提供上下文信息。
Vue 選項(xiàng)中的 render
函數(shù)若存在,則 Vue 構(gòu)造函數(shù)不會(huì)從 template
選項(xiàng)或通過 el
選項(xiàng)指定的掛載元素中提取出的 HTML 模板編譯渲染函數(shù)。
h()函數(shù)用法還是比較多的
// 除了類型必填以外,其他的參數(shù)都是可選的 h('div') h('div', { id: 'foo' }) // attribute 和 property 都能在 prop 中書寫 // Vue 會(huì)自動(dòng)將它們分配到正確的位置 h('div', { class: 'bar', innerHTML: 'hello' }) // props modifiers such as .prop and .attr can be added // with '.' and `^' prefixes respectively h('div', { '.name': 'some-name', '^width': '100' }) // 類與樣式可以像在模板中一樣 // 用數(shù)組或?qū)ο蟮男问綍鴮? h('div', { class: [foo, { bar }], style: { color: 'red' } }) // 事件監(jiān)聽器應(yīng)以 onXxx 的形式書寫 h('div', { onClick: () => {} }) // children 可以是一個(gè)字符串 h('div', { id: 'foo' }, 'hello') // 沒有 props 時(shí)可以省略不寫 h('div', 'hello') h('div', [h('span', 'hello')]) // children 數(shù)組可以同時(shí)包含 vnodes 與字符串 h('div', ['hello', h('span', 'hello')])
得到的 vnode 為如下形式:
const vnode = h('div', { id: 'foo' }, []) vnode.type // 'div' vnode.props // { id: 'foo' } vnode.children // [] vnode.key // null
當(dāng)然我們常見的template的形式(Vue 的模板)實(shí)際上被編譯成了渲染函數(shù)。
export default { render (h) { const p = h('p', 'hi') return h('div', { class: 'red' }, [p, p]) } }
三、函數(shù)式組件
函數(shù)式組件是一種定義自身沒有任何狀態(tài)的組件的方式。它們很像純函數(shù):接收 props,返回 vnodes。函數(shù)式組件在渲染過程中不會(huì)創(chuàng)建組件實(shí)例 (也就是說,沒有 this
),也不會(huì)觸發(fā)常規(guī)的組件生命周期鉤子。
官網(wǎng)函數(shù)式組件格式:
當(dāng)一個(gè)組件沒有管理任何狀態(tài),也沒有監(jiān)聽任何傳遞給它的狀態(tài),也沒有生命周期方法。實(shí)際上,它只是一個(gè)接受一些 prop 的函數(shù)。在這樣的場(chǎng)景下,我們可以將組件標(biāo)記為 functional
,這意味它無狀態(tài) (沒有響應(yīng)式數(shù)據(jù)),也沒有實(shí)例 (沒有 this
上下文)。一個(gè)函數(shù)式組件就像這樣:
export default Vue.component('render-component', { // 該組件抽成js文件, functional: true, // 提供第二個(gè)參數(shù)作為上下文 render: function (createElement, context) { return createElement('h1', '我是函數(shù)式子組件') } })
組件需要的一切都是通過 context
參數(shù)傳遞,它是一個(gè)包括如下字段的對(duì)象:
- props:提供所有 prop 的對(duì)象
- children:VNode 子節(jié)點(diǎn)的數(shù)組
- slots:一個(gè)函數(shù),返回了包含所有插槽的對(duì)象
- scopedSlots:(2.6.0+) 一個(gè)暴露傳入的作用域插槽的對(duì)象。也以函數(shù)形式暴露普通插槽。
- data:傳遞給組件的整個(gè)數(shù)據(jù)對(duì)象,作為 createElement 的第二個(gè)參數(shù)傳入組件
- parent:對(duì)父組件的引用
- listeners:(2.3.0+) 一個(gè)包含了所有父組件為當(dāng)前組件注冊(cè)的事件監(jiān)聽器的對(duì)象。這是 data.on 的一個(gè)別名。
- injections:(2.3.0+) 如果使用了 inject 選項(xiàng),則該對(duì)象包含了應(yīng)當(dāng)被注入的 property。
函數(shù)式組件可以像普通組件一樣被注冊(cè)和使用。如果你將一個(gè)函數(shù)作為第一個(gè)參數(shù)傳入 h
,它將會(huì)被當(dāng)作一個(gè)函數(shù)式組件來對(duì)待。
補(bǔ)充 h函數(shù)使用場(chǎng)景
button.vue
<script> export default { props: { type: { type: String, default: 'normal' }, text: { type: String, default: 'normal' }, size: { type: String, default: 'medium' } }, computed: { tag () { switch (this.type) { case 'success': return 1 case 'danger': return 2 case 'warning': return 3 default: return 1 } } }, render (h) { return h('div', { class: { btn: true, buttom: 'name', 'btn-success': this.type === 'success', 'btn-danger': this.type === 'danger', 'btn-warning': this.type === 'warning', 'btn-mini': this.size === 'mini', 'btn-small': this.size === 'small', 'btn-medium': this.size === 'medium' }, domProps: { innerText: this.text }, on: { click: this.handleClick } }) }, methods: { handleClick () { console.log('button') } } } </script> <style lang="less" scoped> .buttom { padding: 10px 0; margin: 5px; display: flex; align-items: center; justify-content: center; border-radius: 10px; } .buttom:hover { background: #c9c9c9; } .btn-success { background: #48ff8b; color: #fff; } .btn-danger { background: #ff4848; color: #fff; } .btn-warning { background: #ffbf48; color: #fff; } .btn-small { width: 120px; height: 20px; } .btn-medium { width: 120px; height: 30px; } .btn-mini { width: 120px; height: 10px; } </style>
使用
<Button type="danger" text="名字" size="mini"></Button> <Button type="warning" text="名字" size="small"></Button> <Button type="success" text="名字" size="mini"></Button> <Button type="danger" text="名字" size="medium"></Button> <Button type="success" text="名字" size="mini"></Button> <Button type="warning" text="名字" size="medium"></Button>
到此這篇關(guān)于vue中的render函數(shù)、h()函數(shù)、函數(shù)式組件的文章就介紹到這了,更多相關(guān)vue render函數(shù) h()函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在vue中使用eacharts創(chuàng)建graph關(guān)系圖方式
這篇文章主要介紹了在vue中使用eacharts創(chuàng)建graph關(guān)系圖方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09vue-cli3.0 腳手架搭建項(xiàng)目的過程詳解
這篇文章主要介紹了vue-cli3.0 腳手架搭建項(xiàng)目的過程,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-10-10vue項(xiàng)目中使用eslint+prettier規(guī)范與檢查代碼的方法
這篇文章主要介紹了vue項(xiàng)目中使用eslint+prettier規(guī)范與檢查代碼的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01深入探究Vue中$nextTick的實(shí)現(xiàn)原理
這篇文章主要為大家詳細(xì)介紹Vue中$nextTick的實(shí)現(xiàn)原理,文中的示例代碼講解詳細(xì),對(duì)我們深入了解Vue有一定的幫助,需要的小伙伴可以參考一下2023-06-06解決vue?eslint開發(fā)嚴(yán)格模式警告錯(cuò)誤的問題
這篇文章主要介紹了解決vue?eslint開發(fā)嚴(yán)格模式警告錯(cuò)誤的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04