详解在vue项目中使用render函数
详解在vue项目中使用render函数
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript
的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。
基础
如何使用:
render: function (createElement) {
// createElement函数返回结果是VNode
return createElement(
tag, // 标签名称
data, // 传递数据
children // 子节点数组
)
}
详解
render函数涉及到vue里的一个核心思想:虚拟DOM。
Vue 通过建立一个虚拟 DOM 来追踪自己要如何改变真实 DOM。请仔细看这行代码:
return createElement('h1', this.blogTitle)
createElement 到底会返回什么呢?其实不是一个实际的 DOM 元素。它更准确的名字可能是 createNodeDescription,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,包括及其子节点的描述信息。我们把这样的节点描述为“虚拟节点 (virtual node)”,也常简写它为“VNode”。“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。
使用场景
我们看vue官方给出的一个例子,不要细究使用方法,注意Vue.component:
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // 标签名称
this.$slots.default // 子节点数组
)
},
props: {
level: {
type: Number,
required: true
}
}
})
可以看出render函数通过Vue.component最终输出了一个vue组件,为什么要讲这个?
通篇读完vue render函数的文档后,产生了一个非常大的疑问,这个render函数的使用场景是什么?如果说是render函数返回的是虚拟节点,那这个节点应该放在哪呢?这个方法是会包含节点的描述信息,可是生成后的节点放在哪呢?我们肯定是要将渲染出来的节点插入原有的dom结构里,我怎么才知道放在那个节点前?哪个节点后?哪个节点里面?
官方例子确实是创建了一个component,可是我总不能在项目中也Vue.component一个组件吧,有的人肯定想到项目中用的就是组件,怎么到你这又有问题了?往下看。
带着这个问题我找到了一篇文章:
render方法的实质就是生成template模板;
render函数生成的内容相当于template的内容,所以使用render函数时,在.vue文件中需要先把template标签去掉。只保留逻辑层。
意思很明白,在脚手架生成的项目中,.vue文件是通过template渲染的虚拟dom,template底层也是使用的render函数。一个组件最终的模板只能有一个,所以如果在项目中(.vue文件)使用render函数,就要去掉template标签;并且你只能作为组件来使用,不可能整个页面都用render函数js手写页面吧~
如此,便解决了我莫大的疑问。
使用方法
src\components\render\heading.vue
<script>
export default {
props: ["level", "title"],
// heading组件
// <heading :level="1" :title="title" icon="cart">{{title}}</heading>
// <h2 title=""></h2>
render(h) {
console.log("this.$slots.default :>> ", this.$slots.default);
return h(
"h" + this.level, // 参数1,tagname
{ attrs: { title: this.title } }, // 参数2:{。。。}
//this.$slots.default 为默认插槽
//也可以定义具名插槽 this.$slots.名称 | 使用 v-slot:名称 插入
this.$slots.default // 参数3,子节点VNode数组
);
},
};
</script>
<style lang="scss" scoped>
</style>
src\view\test\test2.vue
<template>
<div>
<h2>render函数</h2>
<heading :title="title" :level="level">
{{ title }}
</heading>
</div>
</template>
<script>
import Heading from "../../components/render/heading.vue";
export default {
components: { Heading },
data() {
return {
title: "这是由render函数渲染的标签。",
level: "1",
};
},
};
</script>
<style lang="scss" scoped>
</style>
效果:
更多推荐
所有评论(0)