多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] >[success] # 更加底层的 render 函数 本章讲解一下 **render 函数** ,它是 **vue** 中 **比较底层** 的一块内容,来简单的了解一下。 我们封装了一个 **title 组件**,我们的 **title 组件** 中有一个 **h1 标签**,但是这个 **h几的标签** ,我们想 **通过外部传递的参数来控制** ,那我们肯定第一印象是 **通过 props 传入一个值来进行判断来显示对应的h几的标签** ,我们通过 **template** 以及 **render 函数** 来实现此效果,代码如下: >[success] ## template 实现 ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>更加底层的 render 函数</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // render function // template -> render -> h -> 虚拟DOM(JS 对象) -> 真实DOM -> 展示到页面上 const app = Vue.createApp({ template: ` <my-title :level="2"> hello </my-title > ` }) app.component('my-title', { props: ['level'], template: ` <h1 v-if="level === 1"><slot /></h1> <h2 v-if="level === 2"><slot /></h2> <h3 v-if="level === 3"><slot /></h3> <h4 v-if="level === 4"><slot /></h4> <h5 v-if="level === 5"><slot /></h5> <h6 v-if="level === 6"><slot /></h6> ` }) const vm = app.mount('#root') </script> </html> ~~~ >[success] ## render 函数实现 通过 **render 函数** , 就可以实现非常多的代码实现的功能,而且很简单, **render 函数** 与 **template** 之间的关系是什么呢,实际上 **template** 在 **底层被编译之后** ,会 **生成这个 render函数**,这个 **render 函数** 它里面调用 **vue** 的 **h 方法** 去 **返回一个内容** ,这个内容实际上是 **vue** 中一个叫做 **虚拟dom** 的一个东西,**虚拟dom是什么呢,它实际上是 dom 节点的一个 js对象 的表述** ~~~ // 真实的dom的样子 <div>hello</div> // 虚拟dom的样子(虚拟dom就是js对象,它是对真实dom对象的一个映射) { tagName: 'div', text: hello, attributes: {} } ~~~ 上面的 **真实的 div 会被映射成下面这个 虚拟dom** , **vue** 里面把 **template** 变成 **render 函数** , **render 函数** 再去返回一个 **虚拟 dom** ,它的意义在于什么呢,它有 **2个好处** : 1. **它可以让vue的性能更快** 2. **它可以让vue具备一个跨平台的能力,不仅可以写网页上的东西,还可以通过weex这样的开发工具,去编写移动端的一些代码** ,所以说 **虚拟 dom** 它的作用还是很大的,但是它是一个 **比较深的内容** ,如果大家感兴趣可以查阅相关内容。 **h 函数** 就是返回 **虚拟dom 节点** 的一个 **函数**, **第一个参数是告诉虚拟 dom的标签是什么,第二个参数是标签的属性,第三个参数是标签的内容** 。 上面说了一些 **虚拟dom** 的内容,下面看一下使用 **render 函数** 实现的效果。 ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>更加底层的 render 函数</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // render function // template -> render -> h -> 虚拟DOM(JS 对象) -> 真实DOM -> 展示到页面上 const app = Vue.createApp({ template: ` <my-title :level="5"> hello dell </my-title > ` }) app.component('my-title', { props: ['level'], // 用render实现的代码 render(){ // 引入h函数 const { h } = Vue; // 参数1:标签名字 // 参数2:属性 // 参数3:内容 // 在render函数里面或者在vue的其他函数里面, // 通过this.$slot能获取到slot的相关内容, // 如果调用默认插槽中的内容可以通过this.$slots.default()来获取 return h('h' + this.level, {}, this.$slots.default()) } // 原来的代码 // template: ` // <h1 v-if="level === 1"><slot /></h1> // <h2 v-if="level === 2"><slot /></h2> // <h3 v-if="level === 3"><slot /></h3> // <h4 v-if="level === 4"><slot /></h4> // <h5 v-if="level === 5"><slot /></h5> // <h6 v-if="level === 6"><slot /></h6> // ` }) const vm = app.mount('#root') </script> </html> ~~~ >[success] ## render 函数嵌套 **h函数** 可以 **深层次嵌套** ,这样就可以生成自己想要的结构。 **index.html** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>更加底层的 render 函数</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // render function // template -> render -> h -> 虚拟DOM(JS 对象) -> 真实DOM -> 展示到页面上 const app = Vue.createApp({ template: ` <my-title :level="1"> hello dell </my-title > ` }) app.component('my-title', { props: ['level'], render(){ // 引入h函数 const { h } = Vue; // 参数1:标签名字 // 参数2:属性 // 参数3:内容 // 在render函数里面或者在vue的其他函数里面, // 通过this.$slot能获取到slot的相关内容, // 如果调用默认插槽中的内容可以通过this.$slots.default()来获取 return h('h' + this.level, {}, [ this.$slots.default(), h('h4', {}, 'dell') ]) } }) const vm = app.mount('#root') </script> </html> ~~~