Vue中渲染函数的使用

发布于:2025-06-08 ⋅ 阅读:(25) ⋅ 点赞:(0)

  • vue中的渲染函数:
    • 1.template
    • 2.render函数
    • 3.jsx -> js extension(jsx也是编译成render函数可编程能力更强)

1. render函数

  • 1.1. 认识h函数

    • 1.1.1. Vue推荐在绝大多数情况下使用模板来创建HTML,一些特殊的场景,真的需要javaScript的完全编程的能力,
      这个时候可以使用渲染函数,它比模板更接近编译器。
    • 1.1.2. VNodeVDom的概念
      • Vue在生成真实DOM之前,会将我们的节点转换成VNode, 而VNode组合在一起形成一棵树结构,就是虚拟DOM(VDOM);

      • 事实上,之前编写的template中的HTML最终也是使用渲染函数生成对应的VNode;

      • 如果想重复利用JavaScript的编程能力,可以编写createVNode函数,生成对应的VNode;

      • Vue底层渲染流程如下图:

        <!-- HTML模板 -->            <!--  h函数 -->           <!--  虚拟节点VNode -->         <!--  真实DOM -->
        <template> 
          <div>                      createVNode()                     VNode                          真实DOM
            <h2></h2>                createVNode()                   ↙      ↘                    ↙          ↘  
            <p></p>                  createVNode()                 VNode     VNode               h2             p  
          </div>
        </template>
        

        在这里插入图片描述

  • 1.2. 使用h函数

    • h() 函数是一个用于创建vnode的一个函数;
    • 其实更准确的命名是createVNode()函数,但是为了简便在Vue将之简化为h()函数(本质上是createVNode()函数)

2. h()的使用

  • h()函数接收三个参数:tag, props, children
      { String | Object | Function } tag                             {  Object } props                                    { String | Array | Object } children
      一个HTML标签、一个组件、一个异步组件、或                          与attribute、prop 和事件相对应的对象                    子 VNodes, 使用`h()` 构建
      一个函数式组件                                                  会在模板中使用                                         使用字符串获取 `文本 VNode``有插槽的对象`
      必需的                                                         可选的                                                 可选的
      例如:'div'                                                    { }                                                    [ 
                                                                                                                              'some text comes first',
                                                                                                                              h('h1', null, '哈哈哈哈'),
                                                                                                                              h(myComponent, {someProp: 'fooBar'})
                                                                                                                            ]
        
    
  • 注意事项:
    • 如果没有props, 通常可以将children作为第二个参数传入;
    • 如果会产生歧义,可以将null作为第二个参数传入,将children作为第三个参数传入;
  • HTML转成VNode的调用案例:
      <div class="abc" title='内容'>
        h2
        p
      </div>
    
    
      // 转成VNode:
      createVNode('div', { class: 'abc', title: '内容' }[
        createVNode('h2', null, '我是标题'),
        createVNode('p', { }, '我是内容')
      ])
    
    
    
  • createVNode函数的调用如下图;
    在这里插入图片描述

3. render函数和h函数的区分

  • 流程:render函数是放在对应的组件选项里面的,当渲染组件的时候,会调用render函数,一旦调用就会返回的VNode,为了去创建一系列的VNode, 所以会调用h函数并渲染成HTML

  • 区分:render函数是写到组件里面的,而h函数(createVNode函数)才是真正去创建VNode的

    1. render函数使用
      1. Options API的用法,使用render函数选项
      • 代码如下:
          <script>
            import { h } from 'vue'
            import Home from './Home.vue'
            export default {
              data () {
                return {
                  counter: 0
                }
              },
              render () {
                console.log('this===', this);
                
                return h('div', { class: 'app' } , [
                  h('h2', { class: 'title' }, `当前计数:${ this.counter }`),
                  h('button', { onClick: this.increment }, '+1'),
                  h('button', { onClick: this.decrement }, '-1'),
                  // 在render函数中,引入其他组件不需要注册(components), 在template模板中需要注册
                  h(Home)
                ])
              },
              methods: {
                increment () {
                  this.counter++
                },
                decrement() {
                  this.counter--
                }
              }
            }
          </script>
        
      1. Composition API的用法
      • 2.1. setup函数的使用,
        • 关键点:setup()中返回一个函数,函数中返回VNode
        • setup函数默认返回一个对象 => return { counter, increment, decrement }
        • setup函数中使用render函数,不要返回对象,setup本身需要是返回一个函数类型, 箭头函数中再去返回VNode
        • 代码如如下:
          <script>
          import { h, ref } from 'vue'
          import Home from './Home.vue'
          export default {
            setup () {
              const counter = ref(0)
              
              const increment = () => {
                counter.value++
              }
        
              const decrement = () => {
                counter.value--
              }
        
              // setup函数默认返回一个对象 => return { counter, increment, decrement }
              // setup函数中使用render函数,不要返回对象,返回一个函数, 箭头函数中再去返回VNode
              return () => {
                return h('div', {className: 'app' }, [
                  h('h2', { className: 'title' }, `当前计数: ${ counter.value }`),
                  h('button', { onClick: increment }, '+1'),
                  h('button', { onClick: decrement} , '-1'),
                  h(Home)
                ])
              }
              // return () => h('div', {className: 'app' }, [
              //   h('h2', { className: 'title' }, `当前计数: ${ counter.value }`),
              //   h('button', { onClick: increment }, '+1'),
              //   h('button', { onClick: decrement} , '-1'),
              //   h(Home)
              // ])
            }
          }
          </script>
        
      • 2.2. setup语法糖的使用
        • 在setup中义render函数
        • 在template模板中使用render标签
        • 代码如下;
            <template>
              <render/>
            </template>
          
            <script setup>
              import { ref, h } from 'vue'
              import Home from './Home.vue'
          
              const counter = ref(0)
              
              const increment = () => {
                counter.value++
              }
          
              const decrement = () => {
                counter.value--
              }
          
              // 使用render函数,是为了使用js的方式去编写代码,基本上很少使用
              // 如果依然想使用JS的方式编写,可以使用JSX语法,JSX本质会转化成render函数
              // JSX的优点:1. 快速的编写元素的结构  2. 完全可以利用JS编程能力
              const render = () => h('div', {className: 'app' }, [
                h('h2', { className: 'title' }, `当前计数: ${ counter.value }`),
                h('button', { onClick: increment }, '+1'),
                h('button', { onClick: decrement} , '-1'),
                h(Home)
              ])
          
            </script>
          
          
      1. render函数的使用推荐
      • 使用render函数,是为了使用js的方式去编写代码,基本上很少使用
      • 如果依然想使用JS的方式编写,可以使用JSX语法,JSX本质会转化成render函数
        • JSX的优点
            1. 快速的编写元素的结构
            1. 完全可以利用JS编程能力

网站公告

今日签到

点亮在社区的每一天
去签到