• Vue高级语法(三) | render函数和jsx的基本使用


    h函数的使用

    🍤h函数基本介绍

    Vue推荐在绝大数情况下使用模板来创建你的HTML,然后一些特殊的场景,你真的需要JavaScript的完全编程的能力,这个时候你可以使用渲染函数,它比模板更接近编译器

    前面我们讲解过VNode和VDOM的概念

    Vue在生成真实的DOM之前,会将我们的节点转换成VNode,而VNode组合在一起形成一颗树结构,就是虚拟DOM (VDOM);

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

    那么,如果你想充分的利用JavaScript的编程能力,我们可以自己来编写 createVNode 函数,生成对应的VNode

    我们可以使用 h()函数, 来自己编写createVNode函数

    h() 函数是一个用于创建 vnode 的一个函数;

    其实更准确的命名是 createVNode() 函数,但是为了简便在Vue将之简化为 h() 函数

    h()函数 如何使用呢?它接受三个参数

    第一个参数表示创建的元素

    在这里插入图片描述

    第二个参数可选的, 可以传入null, 也可以传入一个要添加的属性的对象

    在这里插入图片描述

    第三个参数是元素的内容, 可以直接传入一个字符串, 表示创建出来元素的内容

    如果元素中有其他元素, 那么可以传入一个数组, 再次调用h()函数

    在这里插入图片描述

    注意事项

    如果没有props,那么通常可以将children作为第二个参数传入;

    如果会产生歧义,可以将null作为第二个参数传入,将children作为第三个参数传入;

    🍤h函数使用流程

    h函数可以在两个地方使用

    Options API 的render函数选项中;

    setup函数选项中(setup本身需要是一个函数类型,函数再返回h函数创建的VNode);

    例如有如下一个template结构, 我们使用h函数创建出来

    <template>
      <div class="app">
        <h2 class="title">我是标题h2>
    		 <p>我是内容p>
      div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    我们先来看看在Options API中的使用

    import { h } from "vue"
    
    export default {
      render() {
        return h("div", {className: "app"}, [
          h("h2", {className: "title"}, "我是标题"),
          h("p", null, "我是内容"),
        ])
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • render函数不仅可以传入普通元素, 也可以传入一个组件
    import { h } from "vue"
    import Home from "./home.vue"
    
    export default {
      render() {
        return h("div", { className: "app" }, [
          // 因为不是在模板中使用, 因此无需注册, 直接使用
          h(Home)
        ])
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    我们再来看看在Composition API中的使用

    import { h } from "vue"
    
    export default {
      setup() {
        // setup是一个函数, 让这个函数再返回一个函数
        return () => h("div", { class: "app" }, [
          h("h2", { class: "title" }, "我是标题"),
          h("p", null, "我是内容")
        ])
      }
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    🍤h函数案例练习

    在Options API 中使用h函数完成计数器

    import { h } from "vue"
    
    export default {
      data() {
        return {
          conter: 0
        }
      },
      render() {
        return h("div", { className: "app" }, [
          h("h2", null, `当前计数: ${this.conter}`),
          h("button", { onclick: this.increment }, "+"),
          h("button", { onclick: this.decrement }, "-")
        ])
      },
      methods: {
        increment() {
          this.conter ++
        },
        decrement() {
          this.conter --
        }
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在Composition API 中使用h函数完成计数器

    import { h, ref } from "vue"
    
    export default {
      setup() {
        const conter = ref(0)
    
        const increment = () => {
          conter.value ++
        }
    
        const decrement = () => {
          conter.value --
        }
    
        // setup是一个函数, 让这个函数再返回一个h函数
        return () => h("div", { class: "app" }, [
          h("h2", { class: "title" }, `当前计数: ${conter.value}`),
          h("button", { onclick: increment }, "+"),
          h("button", { onclick: decrement }, "-")
        ])
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 如果是在