vue render 渲染函數
經常看到使用render
渲染函數的示例,而且在一些特殊情況下,確實更好使用,可以更加有效地細分組件,因而借助vue-element-admin
來學習一波
render函數分析
- 函數式組件
- 基礎的使用方式
針對 Link.vue進行改造
Link.vue
// https://github.com/vuejs/eslint-plugin-vue/issues/462
<template>
<!-- eslint-disable vue/require-component-is -->
<component v-bind="linkProps(to)">
<slot />
</component>
</template>
<script>
import { isExternal } from '@/utils/validate'
export default {
props: {
to: {
type: String,
required: true
}
},
methods: {
linkProps(url) {
if (isExternal(url)) {
return {
is: 'a',
href: url,
target: '_blank',
rel: 'noopener'
}
}
return {
is: 'router-link',
to: url
}
}
}
}
</script>
上述方式打開了一個新的使用方式,這樣的好處,不需要使用if/else
進行處理,還可以減少一個多余的標簽【root element】。但是會有一些語法提示錯誤,雖然添加了eslint-disable
來禁止,但還是不行,而且有些不似vue
的用法
改造開始
- 版本一 非函數式組件 【Link.vue】
<script>
import { isExternal } from '@/utils/validate'
export default {
name: 'Link',
props: {
to: {
type: String,
required: true
}
},
render(h) {
if (isExternal(this.to)) {
return h(
'a',
{
attrs: {
target: '_blank',
rel: 'noopener',
href: this.to
}
},
this.$slots.default
)
} else {
return h('router-link',
{
props: {
to: this.to
}
},
this.$slots.default
)
}
}
}
</script>
主要是slot
如何處置比較好,其他都好處理,而且使用slot
有兩種方式 插槽
方式一
this.$slots.default
方式二
this.$scopedSlots.default()
- 版本二 函數式組件 【Link.vue】
<script>
import { isExternal } from '@/utils/validate'
export default {
name: 'Link',
functional: true,
props: {
to: {
type: String,
required: true
}
},
render(h, context) {
console.log(context)
const { props, scopedSlots } = context
const { to } = props
if (isExternal(to)) {
return h(
'a',
{
attrs: {
target: '_blank',
rel: 'noopener',
href: to
}
},
scopedSlots.default()
)
} else {
return h('router-link',
{
props: {
to: to
}
},
// scopedSlots.default()
context.children
)
}
}
}
</script>
對於上述兩種實現方式,大致相同,有一些細節需要注意
functional: true
添加這個后,只能通過context
來進行上下文關聯,而無法調用this
,同時這種方式會快一些,只是在使用slot
時,會有兩種形式linkthis.$slots.default
更新為context.children
scopedSlots.default()
這種方式依舊在
- 當時用
functional: true
,文件名便可以改為js
為后綴了,若依舊使用vue
時,便需要<script> export default {}</script>
進行包裹了
總結
render
函數更多是,很多細節不能使用語法糖來進行處理,導致使用起來不順手slot
插槽這塊還是很有用的,只是文檔說明等沒有前面的那么詳細了- 通過上述方式,便發現原來可以這么玩,而且細粒度已經都要一層標簽了,若使用原來的方式,
root element
怕是就夠處理好一會兒了